//COPYRIGHT AND PERMISSION NOTICE
//
//Copyright (c) 1999,2000,2001 Brian Bennewitz
//
//All rights reserved.
//
//Permission is hereby granted, free of charge, to any person obtaining a
//copy of this software and associated documentation files (the
//"Software"), to deal in the Software without restriction, including
//without limitation the rights to use, copy, modify, merge, publish,
//distribute, and/or sell copies of the Software, and to permit persons
//to whom the Software is furnished to do so, provided that the above
//copyright notice(s) and this permission notice appear in all copies of
//the Software and that both the above copyright notice(s) and this
//permission notice appear in supporting documentation.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
//OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
//MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
//OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
//HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
//INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
//FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
//NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
//WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
//Except as contained in this notice, the name of a copyright holder
//shall not be used in advertising or otherwise to promote the sale, use
//or other dealings in this Software without prior written authorization
//of the copyright holder.

#include "stdafx.h"
#include "translhextion.h"
#include "mainwindow.h"
// dialogs
#include "DlgMisc.h"
#include "DlgFind.h"
#include "DlgOffset.h"
// other stuff
#include "float.h"
#include <fstream>
#include <string.h>
#include <winuser.h>

static TCHAR szTitle[MAX_LOADSTRING];			// text for application title bar
static TCHAR szWindowClass[MAX_LOADSTRING];	// name of the class for the main window

extern Translhextion mainwindow;

#define strcpy	_tcscpy
#define strcmp	_tcscmp
#define strlen	_tcslen
#define strcat	_tcscat
#define sscanf	_stscanf
#define sprintf	_stprintf

template<class T>void sswap(T& x, T& y)
{
	T temp = x;
	x = y;
	y = temp;
}

void Translhextion::Create()
{
	hWnd = CreateWindow (szWindowClass,
		szTitle,
		WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
		mainwindow.iWindowX,
		mainwindow.iWindowY+28,
		mainwindow.iWindowWidth,
		mainwindow.iWindowHeight,
		NULL,
		NULL,
		GetAppInstance(),
		this);

	on_window_init(hWnd,GetAppInstance());
}

//takes filestream
//reads in table values
int Translhextion::wread_table_file(LPCTSTR filename)
{
	bReadingTable = true;
	clear_all_bookmark ();
	
	return table.Open(filename, pbmkList, iBookmarkCount);
}

Translhextion::Translhextion ()
{
	HMODULE hInstance=GetModuleHandle(NULL);

	LoadString(hInstance, IDS_SYSTEM_NAME, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDS_SYSTEM_CLASS, szWindowClass, MAX_LOADSTRING);

	WNDCLASSEX window;

	window.cbSize = sizeof (window);
	window.style = CS_HREDRAW | CS_VREDRAW;
	window.lpfnWndProc = MainWndProc;
	window.cbClsExtra = 0;
	window.cbWndExtra = 0;
	window.hInstance = hInstance;
	window.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_ICON1));
	window.hCursor = LoadCursor( NULL, IDC_ARROW );
	window.hbrBackground = (HBRUSH)(COLOR_WINDOW);
	window.lpszMenuName = MAKEINTRESOURCE (IDR_MAINMENU);
	window.lpszClassName = szWindowClass;
	window.hIconSm =LoadIcon(window.hInstance, MAKEINTRESOURCE (IDI_ICON1));

	RegisterClassEx (&window);

	TCHAR * acPath = new TCHAR[MAX_PATH];
	if(GetModuleFileName(NULL,acPath,MAX_PATH) != 0)
	{
		// guaranteed file name of at least one character after path 
		* (_tcsrchr(acPath,'\\')+1) = '\0';
		//	AfxMessageBox(acPath);   // Use it 
	}
	sAppPath = acPath;
	delete [] acPath;
	TCHAR *winpath;
	winpath = new TCHAR[MAX_PATH];
	GetWindowsDirectory(winpath,MAX_PATH);
	sWindowsPath = (_tstring) winpath;
	delete [] winpath;
	bDontMarkCurrentPos = FALSE;

	bInsertingHex = FALSE;

	//sBrowserName = _T("iexplore.exe");
	sTexteditorName = _T("notepad.exe");

	iWindowX = CW_USEDEFAULT;
	iWindowY = CW_USEDEFAULT;
	iWindowWidth = CW_USEDEFAULT;
	iWindowHeight = CW_USEDEFAULT;
	iWindowShowCmd = SW_SHOW;
	IMEPos.left = 0;
	IMEPos.right = 0;
	IMEPos.top = 0;
	IMEPos.bottom = 0;
	iHexWidth = 3;
	iChangesColorValue = cChangesColor;
	iHighlightColorValue = cHighlightColor;
	iBookmarkColor = cBookmarkColor;
	iSelBkColorValue = cSelBkColor;
	iSelTextColorValue = cSelTextColor;
	iTextColorValue = cTextColor;
	iTextColorEValue = cTextColorE;
	iTextColorOValue = cTextColorO;
	iBkColorValue = cBkColor;
	iSepColorValue = cSepColor;
	iDTEColorValue = cDTEColor;
	pcGotoDialogBuffer = NULL;
	iGotoDialogBufLength = 0;
	bOpenReadOnly = bReadOnly = FALSE;
	iPartialOffset=0;
	bPartialOpen=FALSE;
	iBookmarkCount=0;
	//int i;
	// fill empty names for recently opened files
	//for (i=1; i<=iMostRecentMaximum; i++) strMostRecent[i-1].Format(_T("dummy%d"),i);
	//for (i=1; i<=iMostRecentTableMaximum; i++) strMostRecentTable[i-1].Format(_T("dummy%d"),i);
	iMostRecentCount = 0;
	iMostRecentTableCount = 0;
	bFilestatusChanged = TRUE;
	iBinaryMode = LITTLE_ENDIAN;
	//cFileName[0] = '\0';
	bUnsignedView = TRUE;
	iFontSize = 10;
	iInsertMode = FALSE;
	bAutomaticBPL = BST_CHECKED;
	bSelected = FALSE;
	bLButtonIsDown = FALSE;
	iStartOfSelection = 0;
	iEndOfSelection = 0;
	//hwnd = 0;
	iOffsetLength = 8;
	iByteSpace = 2;
	iBytesPerLine = 16;
	iCharSpace = 1;
	iCharsPerLine = iOffsetLength + iByteSpace + iBytesPerLine*3 + iCharSpace + iBytesPerLine;
	filename;
	filename2 = new TCHAR[_MAX_PATH];
	filename.Empty();
	iTextEntryMode = BYTES;
	iFileChanged = FALSE;
	bFileNeverSaved = TRUE;

	iFindDialogLastLength = 0;
	//pcFindDialogBuffer = NULL;
	iFindDialogBufLength = 0;

	iCopyHexdumpDialogStart = 0;
	iCopyHexdumpDialogEnd = 0;
	//iCharacterSet = ANSI_FIXED_FONT;
	iCharacterSet=ENCODING_BYTE;
	
	count_instances();
	read_ini_data ();

	bFileNeverSaved = TRUE;
	bSelected = FALSE;
	bLButtonIsDown = FALSE;
	iFileChanged = FALSE;
	iVerticalScrollMax = 0;
	iVerticalScrollPos = 0;
	iVerticalScrollInc = 0;
	iHorizontalScrollMax = 0;
	iHorizontalScrollPos = 0;
	iHorizontalScrollInc = 0;
	iCurrentLine = 0;
	iCurrentByte = 0;
	FileBuffer.Reset ();
	vChanges = vEmpty;
	vHighlights = vEmpty;
	vDTEs = vEmpty;
	FileBuffer.SetExpandBy (100);
	filename=_T("Untitled");
	//AddFontResource("Januschan JOME Regular.ttf");
	AddFontResource(_T("Courier New"));
	//LoadEncoding();
}

Translhextion::~Translhextion ()
{
	if (hFont != NULL)
		DeleteObject (hFont);
	if(!RemoveFontResource(_T("Courier New")/*Januschan JOME Regular.ttf"*/))
		MessageBox(_T("Japanese font could not be removed from memory!"),_T("Garbage collection error:"),MB_OK | MB_ICONERROR);
	if (hfJap != NULL)
		DeleteObject (hfJap);
	//if (pcFindDialogBuffer != NULL)
	//	delete [] pcFindDialogBuffer;
	if( pcGotoDialogBuffer != NULL )
		delete [] pcGotoDialogBuffer;
	if( filename2)
		delete[] filename2;

	ReleaseWindowText();
}

void Translhextion::EnableToolbarButton(UINT uID, bool enable)
{
	SendMessage(hToolbar,TB_ENABLEBUTTON,uID,(LPARAM)enable);
}

bool Translhextion::CreateToolbar()
{
	TBBUTTON tbb[21];
	struct pair{u32 id; u32 icon;} ids[]=
	{
		IDM_NEW,0,
		IDM_OPEN,1,
		IDM_SAVE,2,
		-1,-1,
		IDM_EDIT_CUT,6,
		IDM_EDIT_COPY,7,
		IDM_EDIT_PASTE,8,
		-1,-1,
		IDM_FIND,3,
		IDM_HEXFIND,4,
		IDM_FINDNEXT,11,
		IDM_FINDPREV,12,
		-1,-1,
		IDM_OPEN_TABLE,20,
		IDM_SCRIPT_DUMP,14,
		IDM_REPLACE_SCRIPT,17,
		IDM_OPTIMIZESCRIPT,13,
		-1,-1,
		IDM_VIEW_SETTINGS,5,
		IDM_COLOR_SETTINGS,19,
		IDM_ABOUT,15
	};

	ZeroMemory(tbb,sizeof(tbb));
	for(int i=0; i<sizeof(ids) / sizeof(*ids); i++)
	{
		if(ids[i].icon!=-1 && ids[i].id!=-1)
		{
			tbb[i].iBitmap = ids[i].icon;
			tbb[i].idCommand = ids[i].id;
			tbb[i].fsStyle = BTNS_BUTTON;
		}
		else tbb[i].fsStyle = BTNS_SEP | BTNS_BUTTON;
		//tbb[i].fsState = TBSTATE_ENABLED;
	}

	hToolbar=CreateToolbarEx(*this,
		WS_CHILD | WS_VISIBLE,IDR_MAINTOOLBAR,
		(UINT)IDR_MAINTOOLBAR,
		hInstance,
		(UINT)IDR_MAINTOOLBAR,
		tbb,
		sizeof(tbb) / sizeof(*tbb),
		16,16,16,16,
		sizeof(TBBUTTON));

	HIMAGELIST imageList = ImageList_LoadImage(hInstance,MAKEINTRESOURCE(IDB_MAINTOOLBAR32),16,0,CLR_DEFAULT,IMAGE_BITMAP,LR_CREATEDIBSECTION|LR_LOADTRANSPARENT);
	SendMessage(hToolbar, TB_SETIMAGELIST, 0, (LPARAM)imageList);

	SendMessage(hToolbar, TB_AUTOSIZE, 0, 0);
	ShowWindow(hToolbar, SW_SHOW);

	EnableToolbarButton(IDM_NEW,true);
	EnableToolbarButton(IDM_OPEN,true);
	EnableToolbarButton(IDM_OPEN_TABLE,true);
	EnableToolbarButton(IDM_VIEW_SETTINGS,true);
	EnableToolbarButton(IDM_COLOR_SETTINGS,true);
	EnableToolbarButton(IDM_ABOUT,true);

	return true;
}

int Translhextion::load_file (LPCTSTR fFileName)
{
	if (file_can_load (fFileName))
	{		
		int iFileHandle;
		if ((iFileHandle = _topen (fFileName,_O_RDONLY|_O_BINARY,_S_IREAD|_S_IWRITE)) != -1)
		{
			long iFileLength = _filelength (iFileHandle);
			FileBuffer.Reset ();
			vChanges = vEmpty;
			vHighlights = vEmpty;
			vDTEs = vEmpty;
			
			if (FileBuffer.SetLength (iFileLength) == TRUE)
			{
				SetCursor (LoadCursor (NULL, IDC_WAIT));
				std::vector<_tstring> temp(iFileLength);
				vChanges = temp;
				vHighlights = temp;
				vDTEs = temp;
				//long m = 0;
				//for(m = 0;m<vChanges.size();m++)
				//	vChanges[m] = COLORNORMAL;
				// If read-only mode on opening is enabled:
				if( bOpenReadOnly )
					bReadOnly = TRUE;
				else
					bReadOnly = FALSE;

				if( iFileLength == 0)
				{
					_close( iFileHandle );
					filename=fFileName;
					bFileNeverSaved = FALSE;
					bPartialOpen=FALSE;
					update_most_recent ();
					bFilestatusChanged = TRUE;
					update_size_change();
					return TRUE;
				}
				else
				{
					FileBuffer.SetUpperBound (iFileLength-1);
					if (_read (iFileHandle, FileBuffer, FileBuffer.Length ()) != -1)
					{
						_close (iFileHandle);
						filename=fFileName;
						bFileNeverSaved = FALSE;
						bPartialOpen=FALSE;
						/*if(bHighlight)
						{
							if(vChanges.size() == 1)
							{
								if(vTwoByteHighlightTable[(unsigned char) FileBuffer[0]] == "1")
								{
									vChanges[0] = COLORHIGHLIGHT;
								}
							}
							else if(vChanges.size() == 2)
							{
								if(vTwoByteHighlightTable[dualtileindex("" + (unsigned char) FileBuffer[0] + (unsigned char) FileBuffer[1])] == "1")
								{
									vChanges[0] = COLORHIGHLIGHT;
									vChanges[1] = COLORHIGHLIGHT;
								}
								else if(vTwoByteHighlightTable[(unsigned char) FileBuffer[0]] == "1")
								{
									vChanges[0] = COLORHIGHLIGHT;
									if(vTwoByteHighlightTable[(unsigned char) FileBuffer[1]] == "1")
									{
										vChanges[1] = COLORHIGHLIGHT;
									}
								}
							}
							else if(vChanges.size() > 2)
							{
								long k = 0;
								string temp;
								for(k = 0;k<vChanges.size()-1;k++)
								{
									temp = "";
									temp += (unsigned char) FileBuffer[k];
									temp += (unsigned char) FileBuffer[k+1];
									//assert(temp.length() == 2);
									if(temp.length() == 2 && vTwoByteHighlightTable[dualtileindex(temp)] == "1")
									{
										vChanges[k] = COLORHIGHLIGHT;
										vChanges[k+1] = COLORHIGHLIGHT;
									}
									else if(vTwoByteHighlightTable[(unsigned char) FileBuffer[k]] == "1")
									{
										vChanges[k] = COLORHIGHLIGHT;
									}
								}
								if(vTwoByteHighlightTable[(unsigned char) FileBuffer[k]] == "1")
								{
									vChanges[k] = COLORHIGHLIGHT;
								}
							}
						}*/
						update_most_recent ();
						bFilestatusChanged = TRUE;
						update_size_change();
						SetCursor (LoadCursor (NULL, IDC_ARROW));
						return TRUE;
					}
					else
					{
						_close (iFileHandle);
						SetCursor (LoadCursor (NULL, IDC_ARROW));
						MessageBox (_T("Error occurred while reading from file."), _T("File load error:"), MB_OK | MB_ICONERROR);
						return FALSE;
					}
				}
				SetCursor (LoadCursor (NULL, IDC_ARROW));
			}
			else
			{
				MessageBox (_T("Not enough memory to load file."), _T("File load error:"), MB_OK | MB_ICONERROR);
				return FALSE;
			}
		}
		else
		{
			GString message;
			message.Format(_T("Error code 0x%X occured while opening file %s."), errno, fFileName);
			MessageBox (message, _T("File load error:"), MB_OK | MB_ICONERROR);
			return FALSE;
		}
	}
	else
		return FALSE;
}

int Translhextion::file_can_load (LPCTSTR fFileName)
{
	int iFileHandle;
	if ((iFileHandle = _topen (fFileName,_O_RDONLY|_O_BINARY,_S_IREAD|_S_IWRITE)) != -1)
	{
		_close (iFileHandle);
		return TRUE;
	}
	else
		return FALSE;
}

int Translhextion::on_window_init (HWND hw, HINSTANCE hI)
{
	hMainWnd = hw;
	hInstance = hI;

	InitCommonControls ();
	hwndStatusBar = CreateStatusWindow (
		 CCS_BOTTOM | WS_CHILD | WS_VISIBLE /*| SBARS_SIZEGRIP*/,
		_T("Ready"), *this, 2);

	//hwndHBar = CreateWindow (_T("scrollbar"), NULL, WS_CHILD | WS_VISIBLE | SBS_HORZ,
	//	0,0,0,0, hwnd, (HMENU) 1, hInstance, NULL);
	//hwndVBar = CreateWindow (_T("scrollbar"), NULL, WS_CHILD | WS_VISIBLE | SBS_VERT,
	//	0,0,0,0, hwnd, (HMENU) 2, hInstance, NULL);

	iVerticalScrollMax = 0;
	iVerticalScrollPos = 0;
	iVerticalScrollInc = 0;
	iHorizontalScrollMax = 0;
	iHorizontalScrollPos = 0;
	iHorizontalScrollInc = 0;

	iCurrentLine = 0;
	iCurrentByte = 0;
	iCurrentNibble = 0;

	CreateToolbar();

	RECT rClient, rTool, rBar;
	GetClientRect(&rClient);
	GetClientRect(hToolbar,&rTool);
	GetClientRect(hwndStatusBar,&rBar);

	int th=rTool.bottom-rTool.top;
	int bh=rBar.bottom-rBar.top;
	int wh=rClient.bottom-rClient.top;

	m_Frame.Create(0,th,64,64,*this);
	m_Frame.SetHorzScrollbar();
	m_Frame.m_Scroll_h.SetScrollInfo(SIF_RANGE | SIF_PAGE | SIF_POS, 0, 222, 54, 88);
	m_Frame.SetVertScrollbar();
	m_Frame.SetStyle(m_Frame.GetStyle() | WS_VSCROLL | WS_HSCROLL);
	m_Frame.hFont=hFont;
	m_Frame.FileBuffer=&FileBuffer;

	//SetWindowPos(hwnd, NULL,rClient.left,rClient.top+th,rClient.right,wh-/*bh-*/th,SWP_NOZORDER);
	
	DragAcceptFiles( *this, TRUE ); 
	return TRUE;
}

int Translhextion::resize_window (int cx, int cy)
{
	HDC hdc = GetDC (*this);
	make_font ();
	make_jfont ();
	HFONT of = (HFONT) SelectObject( hdc, hFont );
	TEXTMETRIC tm;
	GetTextMetrics (hdc, &tm);
	cCharXDim = tm.tmAveCharWidth/*/2+tm.tmAveCharWidth*/;
	cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cCharXDim / 2;
	cCharYDim = tm.tmHeight + tm.tmExternalLeading;
	SelectObject (hdc, of);
	ReleaseDC (*this, hdc);
	
	int /*x, y, x2,*/ h1, h2;
	RECT rWindow, tWindow;
	GetWindowRect (hwndStatusBar, &rWindow);
	GetWindowRect (hToolbar, &tWindow);
	h1 = tWindow.bottom - tWindow.top;
	h2 = rWindow.bottom - rWindow.top;

	cClientYPos=h1;
	//MoveWindow(hToolbar,0,0,tWindow.right,tWindow.bottom,true);
	MoveWindow (hwndStatusBar,0,cy-h2,cx,h2,TRUE);
	//MoveWindow(hwnd,x,h1,cx,cy-h1-y2,TRUE);

	cClientXDim = cx;
	cClientYDim = cy-h2;

	//int cyh = GetSystemMetrics (SM_CYHSCROLL),
	//	cxv = GetSystemMetrics (SM_CXVSCROLL);
	//MoveWindow (hwndHBar, 0, cClientYDim-cyh, cClientXDim - cxv, cyh, FALSE);
	//MoveWindow (hwndVBar, cClientXDim - cxv, h1, cxv, cClientYDim-h1, FALSE);
	//RedrawWindow (hwndHBar, NULL, NULL, RDW_INVALIDATE | RDW_ERASENOW | RDW_ALLCHILDREN);
	//RedrawWindow (hwndVBar, NULL, NULL, RDW_INVALIDATE | RDW_ERASENOW | RDW_ALLCHILDREN);

	//cClientXDim -= cxv;
	//cClientYDim -= (cyh/*+h1*/);

	m_Frame.Resize(0,h1,cClientXDim,cClientYDim-h1);
	m_Frame.hFont=hFont;

	int iStatusBarXDim;
	if (IsZoomed (*this))
		iStatusBarXDim = cx;
	else
		iStatusBarXDim = cClientXDim;
    
    HLOCAL hloc = LocalAlloc (LHND, sizeof(int) * 3);
    int* lpParts = (int*) LocalLock(hloc); 
 
    lpParts[0] = iStatusBarXDim*4/6;
	lpParts[1] = iStatusBarXDim*5/6;
	lpParts[2] = iStatusBarXDim;

    SendMessage (hwndStatusBar, SB_SETPARTS, (WPARAM) 3,
        (LPARAM) lpParts);
 
    LocalUnlock(hloc); 
    LocalFree(hloc);
	
	cxBuffer = max (1, cClientXDim / cCharXDim);
	cBufferY = max (1, cClientYDim / cCharYDim);
	if( bAutomaticBPL )
	{
		int bytemax = cxBuffer-iOffsetLength-iByteSpace-iCharSpace;
		iBytesPerLine = bytemax / 4;
		if (iBytesPerLine < 1)
			iBytesPerLine = 1;
		//Autosize alternating colors
		else if(iBytesPerLine % 2 != 0)
			iBytesPerLine--;
	}
	
	if( bSelected )
	{
		if( iEndOfSelection / iBytesPerLine < iCurrentLine || iEndOfSelection / iBytesPerLine > iCurrentLine + cBufferY )
			iCurrentLine = max( 0, iEndOfSelection / iBytesPerLine - cBufferY / 2 );
	}
	else
	{
		if(iBytesPerLine == 0)
			iBytesPerLine = 1;
		if( iCurrentByte/iBytesPerLine < iCurrentLine || iCurrentByte/iBytesPerLine > iCurrentLine + cBufferY )
			iCurrentLine = max( 0, iCurrentByte/iBytesPerLine-cBufferY/2 );
	}
	update_vertical_scrollbar();
	
	if(!bThingyView)
	{
		iCharsPerLine = iOffsetLength + iByteSpace + iBytesPerLine*3 + iCharSpace + iBytesPerLine;
	}
	else
	{
		iCharsPerLine = iOffsetLength + iByteSpace + iBytesPerLine*2 + iMaxCharLine + iCharSpace + iBytesPerLine;
	}
	if ((FileBuffer.Length()+1) % iBytesPerLine == 0)
		iNumlines = (FileBuffer.Length()+1) / iBytesPerLine;
	else
		iNumlines = (FileBuffer.Length()+1) / iBytesPerLine + 1;
	
	if (iNumlines <= 0xffff)
		iVerticalScrollMax = iNumlines-1;
	else
		iVerticalScrollMax = 0xffff;

	//SetScrollRange (hwndVBar, SB_CTL, 0, iVerticalScrollMax, FALSE);
	//SetScrollPos (hwndVBar, SB_CTL, iVerticalScrollPos, TRUE);
	iHorizontalScrollMax = iCharsPerLine - 1;
	iHorizontalScrollPos = 0;
	//SetScrollRange (hwndHBar, SB_CTL, 0, iHorizontalScrollMax, FALSE);
	//SetScrollPos (hwndHBar, SB_CTL, iHorizontalScrollPos, TRUE);

	// toolbar stuff
	SendMessage(hToolbar, TB_AUTOSIZE, 0, 0);

	update_window_status ();
	if (*this == GetFocus ()) place_cursor ();
	//repaint ();
	return TRUE;
}

int Translhextion::set_focus ()
{
	if (cCharXDim == 0 || cCharYDim == 0)
	{
		make_font ();
		make_jfont ();
		HDC hdc = GetDC (*this);
		HFONT of = (HFONT) SelectObject (hdc, hFont);
		TEXTMETRIC tm;
		GetTextMetrics (hdc, &tm);
		cCharXDim = tm.tmAveCharWidth;
		cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cCharXDim / 2;
		cCharYDim = tm.tmHeight + tm.tmExternalLeading;
		SelectObject (hdc, of);
		ReleaseDC (*this, hdc);
	}
	update_size_change ();
	CreateCaret (*this, NULL, cCharXDim, cCharYDim);
	place_cursor ();
	ShowCaret (*this);
	return 0;
}

int Translhextion::kill_focus ()
{
	HideCaret (*this);
	DestroyCaret ();
	return TRUE;
}



int Translhextion::keydown (int key)
{
	if (filename.IsEmpty() || iCurrentByte<0)
		return 0;

	int iColumn_logical, iScrollFlag;

	if (bSelected)
		switch (key)
		{
		case VK_END:
		case VK_HOME:
		case VK_LEFT:
		case VK_RIGHT:
		case VK_UP:
		case VK_DOWN:
		case VK_PRIOR:
		case VK_NEXT:
			iCurrentByte = iEndOfSelection;
			bSelected = FALSE;
			update_vertical_scrollbar ();
			repaint ();
		default:
			break;
		}

	switch (key)
	{
	case VK_HOME:
	{
		iCurrentByte = (iCurrentByte / iBytesPerLine) * iBytesPerLine;
		iCurrentNibble = 0;
		if (iTextEntryMode == BYTES)
			iColumn_logical = (iOffsetLength + iByteSpace + (iCurrentByte % iBytesPerLine) * 3 + iCurrentNibble);
		else
			iColumn_logical = ((iOffsetLength + iByteSpace + iBytesPerLine * 3 + iCharSpace) + (iCurrentByte % iBytesPerLine));
		if (iColumn_logical < iHorizontalScrollPos) 
		{
			iHorizontalScrollPos = iColumn_logical;
			update_horizontal_scrollbar ();
			repaint ();
		}
		else
		{
			repaint ((iCurrentByte / iBytesPerLine));
		}
		if ((iCurrentLine > (iCurrentByte / iBytesPerLine)) || (iCurrentLine+cBufferY-1 < (iCurrentByte / iBytesPerLine)))
		{
			iCurrentLine = max (0, iCurrentByte/iBytesPerLine-cBufferY/2);
			update_vertical_scrollbar ();
			repaint ();
		}
		break;
	}
	
	case VK_END:
	{
		iCurrentByte = ((iCurrentByte / iBytesPerLine) + 1) * iBytesPerLine - 1;
		if (iCurrentByte > (FileBuffer.Upper ())+1)
			iCurrentByte = (FileBuffer.Upper ())+1;
		iCurrentNibble = 1;

		if (iTextEntryMode == BYTES)
			iColumn_logical = (iOffsetLength + iByteSpace + (iCurrentByte % iBytesPerLine) * 3 + iCurrentNibble);
		else
			iColumn_logical = ((iOffsetLength + iByteSpace + iBytesPerLine * 3 + iCharSpace) + (iCurrentByte % iBytesPerLine));
		
		if (iColumn_logical > (iHorizontalScrollPos + cxBuffer - 1))
		{
			iHorizontalScrollPos = iColumn_logical - cxBuffer + 1;
			update_horizontal_scrollbar ();
			repaint ();
		}
		else
		{
			repaint ((iCurrentByte / iBytesPerLine));
		}
		
		if ((iCurrentLine > (iCurrentByte / iBytesPerLine)) || (iCurrentLine+cBufferY-1 < (iCurrentByte / iBytesPerLine)))
		{
			iCurrentLine = max (0, iCurrentByte/iBytesPerLine-cBufferY/2);
			update_vertical_scrollbar ();
			repaint ();
		}
		break;
	}

	case VK_UP:
		if (iCurrentByte >= iBytesPerLine)
			iCurrentByte -= iBytesPerLine;
		iScrollFlag = FALSE;
		if ((iCurrentLine > (iCurrentByte / iBytesPerLine)) || (iCurrentLine+cBufferY-1 < (iCurrentByte / iBytesPerLine)))
		{
			update_vertical_scrollbar ();
			iScrollFlag = TRUE;
		}

		if (iTextEntryMode == BYTES)
			iColumn_logical = (iOffsetLength + iByteSpace + (iCurrentByte % iBytesPerLine) * 3 + iCurrentNibble);
		else
			iColumn_logical = ((iOffsetLength + iByteSpace + iBytesPerLine * 3 + iCharSpace) + (iCurrentByte % iBytesPerLine));

		if (iColumn_logical < iHorizontalScrollPos || iColumn_logical > (iHorizontalScrollPos + cxBuffer - 1))
		{
			iHorizontalScrollPos = iColumn_logical;
			update_horizontal_scrollbar ();
			repaint ();
			break;
		}
		else if (!iScrollFlag)
		{
			repaint ((iCurrentByte / iBytesPerLine)+1);
			repaint ((iCurrentByte / iBytesPerLine));
		}
		else 
		{
			if (iCurrentLine-(iCurrentByte / iBytesPerLine)==1) 
			{
				iCurrentLine = (iCurrentByte / iBytesPerLine);
				RECT r;
				r.left = BORDER_CLIENT_XDIM;
				r.top = BORDER_CLIENT_XDIM+cClientYPos;
				r.right = cClientXDim - BORDER_CLIENT_XDIM;
				r.bottom = cClientYDim - BORDER_CLIENT_XDIM;
				ScrollWindow (*this, 0, cCharYDim, &r, &r);
				repaint ((iCurrentByte / iBytesPerLine)+1);
				repaint ((iCurrentByte / iBytesPerLine));
			}
			else
			{
				iCurrentLine = (iCurrentByte / iBytesPerLine);
				repaint ();
			}
		}
		break;

	case VK_DOWN:
		
		if (iCurrentByte+iBytesPerLine <= FileBuffer.Length())
			iCurrentByte += iBytesPerLine;
		
		iScrollFlag = FALSE;
		if ((iCurrentLine > (iCurrentByte / iBytesPerLine)) || (iCurrentLine+cBufferY-1 < (iCurrentByte / iBytesPerLine)))
		{
			update_vertical_scrollbar ();
			iScrollFlag = TRUE;
		}

		if (iTextEntryMode == BYTES)
			iColumn_logical = (iOffsetLength + iByteSpace + (iCurrentByte % iBytesPerLine) * 3 + iCurrentNibble);
		else
			iColumn_logical = ((iOffsetLength + iByteSpace + iBytesPerLine * 3 + iCharSpace) + (iCurrentByte % iBytesPerLine));

		if (iColumn_logical < iHorizontalScrollPos || iColumn_logical > (iHorizontalScrollPos + cxBuffer - 1))
		{
			iHorizontalScrollPos = iColumn_logical;
			update_horizontal_scrollbar ();
			repaint ();
			break;
		}
		else if (!iScrollFlag)
		{
			repaint ((iCurrentByte / iBytesPerLine)-1);
			repaint ((iCurrentByte / iBytesPerLine));
		}
		else 
		{
			if ((iCurrentByte / iBytesPerLine)==iCurrentLine+cBufferY) 
			{
				iCurrentLine = max (0, (iCurrentByte / iBytesPerLine)-(cBufferY-1)); 
				RECT r;
				r.left = BORDER_CLIENT_XDIM;
				r.top = BORDER_CLIENT_XDIM+cClientYPos;
				r.right = cClientXDim - BORDER_CLIENT_XDIM;
				r.bottom = cClientYDim - BORDER_CLIENT_XDIM;
				ScrollWindow (*this, 0, -cCharYDim, &r, &r);
				repaint ((iCurrentByte / iBytesPerLine)-1);
				repaint ((iCurrentByte / iBytesPerLine));
				repaint ((iCurrentByte / iBytesPerLine)+1);
				//if(!bThingyView)
				//{
					invert_char( 0 );
				//}
				//else
				//{
				//	thingy_view_invert_char (0);
				//}
				
			}
			else
			{
				iCurrentLine = max (0, (iCurrentByte / iBytesPerLine)-(cBufferY-1));
				repaint ();
			}
		}
		break;
	
	case VK_LEFT:
	{
		if (iTextEntryMode == BYTES) 
		{
			if (iCurrentNibble == 1) 
				iCurrentNibble = 0;
			else if (iCurrentByte != 0) 
			{
				iCurrentByte--;
				iCurrentNibble = 1;
			}
		}
		else 
		{
			if (iCurrentByte != 0)
				iCurrentByte--; 
		}

		
		iScrollFlag = FALSE;
		if ((iCurrentLine > (iCurrentByte / iBytesPerLine)) || (iCurrentLine+cBufferY-1 < (iCurrentByte / iBytesPerLine)))
		{
			iCurrentLine = (iCurrentByte / iBytesPerLine);
			update_vertical_scrollbar ();
			iScrollFlag = TRUE;
		}
		
		if (iTextEntryMode == BYTES)
			iColumn_logical = (iOffsetLength + iByteSpace + (iCurrentByte % iBytesPerLine) * 3 + iCurrentNibble);
		else
			iColumn_logical = ((iOffsetLength + iByteSpace + iBytesPerLine * 3 + iCharSpace) + (iCurrentByte % iBytesPerLine));

		if (iColumn_logical < iHorizontalScrollPos)
		{
			iHorizontalScrollPos = iColumn_logical;
			update_horizontal_scrollbar ();
			repaint ();
			break;
		}
		else if (iColumn_logical > (iHorizontalScrollPos + cxBuffer - 1))
		{
			iHorizontalScrollPos = iColumn_logical-(cxBuffer-1);
			update_horizontal_scrollbar ();
			repaint ();
			break;
		}
		else if (!iScrollFlag)
		{
			if (iCurrentByte%iBytesPerLine==iBytesPerLine-1) 
				repaint ((iCurrentByte / iBytesPerLine)+1);
			repaint ((iCurrentByte / iBytesPerLine));
		}
		else
			repaint ();
		break;
	}

	case VK_RIGHT:
	{
		if (iTextEntryMode == BYTES)
		{
			if (iCurrentNibble == 0)
				iCurrentNibble = 1;
			else if (iCurrentByte <= (FileBuffer.Upper ()))
			{
				iCurrentNibble = 0;
				iCurrentByte++;
			}
		}
		else
		{
			if (iCurrentByte <= (FileBuffer.Upper ()))
				iCurrentByte++;
		}
		
		iScrollFlag = FALSE;
		if ((iCurrentLine > (iCurrentByte / iBytesPerLine)) || (iCurrentLine+cBufferY-1 < (iCurrentByte / iBytesPerLine)))
		{
			iCurrentLine = max ((iCurrentByte / iBytesPerLine)-cBufferY+1, 0);
			update_vertical_scrollbar ();
			iScrollFlag = TRUE;
		}

		if (iTextEntryMode == BYTES)
			iColumn_logical = (iOffsetLength + iByteSpace + (iCurrentByte % iBytesPerLine) * 3 + iCurrentNibble);
		else
			iColumn_logical = ((iOffsetLength + iByteSpace + iBytesPerLine * 3 + iCharSpace) + (iCurrentByte % iBytesPerLine));

		if (iColumn_logical >= iHorizontalScrollPos+cxBuffer)
		{
			iHorizontalScrollPos = iColumn_logical-(cxBuffer-1);
			update_horizontal_scrollbar ();
			repaint ();
			break;
		}
		else if (iColumn_logical < iHorizontalScrollPos)
		{
			iHorizontalScrollPos = iColumn_logical;
			update_horizontal_scrollbar ();
			repaint ();
			break;
		}
		else if (iScrollFlag != TRUE) 
		{
			if (iCurrentByte%iBytesPerLine==0)
				repaint ((iCurrentByte / iBytesPerLine)-1);
			repaint ((iCurrentByte / iBytesPerLine));
		}
		else
			repaint ();
		break;
	}

	case VK_PRIOR:
		if ((iCurrentByte / iBytesPerLine) >= cBufferY)
		{
			iCurrentByte -= cBufferY * iBytesPerLine; 
			iCurrentLine -= cBufferY;
			if (iCurrentLine < 0)
				iCurrentLine = (iCurrentByte / iBytesPerLine);
		}
		else
		{
			iCurrentLine = 0; 
			iCurrentByte = (iCurrentByte % iBytesPerLine);
		}
		if ((iCurrentLine > (iCurrentByte / iBytesPerLine)) || (iCurrentLine+cBufferY-1 < (iCurrentByte / iBytesPerLine)))
			iCurrentLine = iCurrentByte/iBytesPerLine;
		update_vertical_scrollbar ();
		repaint ();
		break;

	case VK_NEXT:
		iCurrentByte += cBufferY*iBytesPerLine;
		if (iCurrentByte > (FileBuffer.Upper ())+1)
		{
			iCurrentByte = ((FileBuffer.Upper ())+1)/iBytesPerLine*iBytesPerLine + (iCurrentByte % iBytesPerLine);
			if (iCurrentByte > (FileBuffer.Upper ())+1)
				iCurrentByte = (FileBuffer.Upper ())+1;
			iCurrentLine = (iCurrentByte / iBytesPerLine);
			adjust_view_for_cursor ();
		}
		else
		{
			iCurrentLine += cBufferY;
			if (iCurrentLine > (iNumlines-1))
				iCurrentLine = (iCurrentByte / iBytesPerLine);
		}
		if ((iCurrentLine > (iCurrentByte / iBytesPerLine)) || (iCurrentLine+cBufferY-1 < (iCurrentByte / iBytesPerLine)))
			iCurrentLine = max ((iCurrentByte / iBytesPerLine)-cBufferY+1, 0);
		update_vertical_scrollbar ();
		repaint ();
		break;
	}
	return 0;
}

int Translhextion::character (char ch)
{
	if (bSelected)
		return 0;

	if( bReadOnly && ch != '\t' )
	{
		MessageBox(_T("File cannot be changed in read-only mode!"), _T("Editing error:"), MB_OK | MB_ICONERROR );
		return 0;
	}

	char x, c = tolower (ch);
	if (ch == '\t') 
	{
		if (iTextEntryMode == BYTES)
			iTextEntryMode = CHARS;
		else
			iTextEntryMode = BYTES;
		
		int iColumn_logical;
		if (iTextEntryMode == BYTES)
			iColumn_logical = (iOffsetLength + iByteSpace + (iCurrentByte % iBytesPerLine) * 3 + iCurrentNibble);
		else
			iColumn_logical = ((iOffsetLength + iByteSpace + iBytesPerLine * 3 + iCharSpace) + (iCurrentByte % iBytesPerLine));

		if (iColumn_logical >= iHorizontalScrollPos+cxBuffer) 
			iHorizontalScrollPos = iColumn_logical-(cxBuffer-1); 
		else if (iColumn_logical < iHorizontalScrollPos) 
			iHorizontalScrollPos = iColumn_logical; 
		update_horizontal_scrollbar ();
		repaint ();
		return 0;
	}

	if( bReadOnly )
		return 1;
	
	if (iTextEntryMode==BYTES && !((c>='a'&&c<='f')||(c>='0'&&c<='9')))
		return 1;

	if (iCurrentByte == FileBuffer.Length())
	{
		if (FileBuffer.InsertExpandOn(iCurrentByte, 0, 1) == TRUE)
		{
			vChanges.push_back(COLORCHANGE);
			iCurrentNibble = 0;
			iInsertMode = FALSE;
			character (ch);
			update_size_change ();
			return 1;
		}
		else
		{
			MessageBox (_T("Not enough memory to insert character."), _T("Insertion error:"), MB_OK | MB_ICONERROR);
		}
		return 0;
	}

	if( iInsertMode )
	{
		if( iTextEntryMode == BYTES )
		{
			if( ( c >= 'a' && c <= 'f' ) || ( c >= '0' && c <= '9' ) )
			{
				if( bInsertingHex )
				{
					bInsertingHex = FALSE;
					if (c >= 'a' && c <= 'f')
						x = c - 0x61 + 0x0a;
					else
						x = c - 0x30;
					FileBuffer[iCurrentByte] = (FileBuffer[iCurrentByte] & 0xf0) | x;
					vChanges[iCurrentByte] = COLORCHANGE;
					iFileChanged = TRUE;
					bFilestatusChanged = TRUE;
					iCurrentByte++;
					iCurrentNibble = 0;
					update_size_change();
				}
				else
				{
					if( FileBuffer.InsertExpandOn( iCurrentByte, 0, 1 ) == TRUE )
					{
						vChanges.push_back(COLORCHANGE);
						bInsertingHex = TRUE;
						if (c >= 'a' && c <= 'f')
							x = c - 0x61 + 0x0a;
						else
							x = c - 0x30;
						FileBuffer[iCurrentByte] = (FileBuffer[iCurrentByte] & 0x0f) | (x << 4);
						vChanges[iCurrentByte] = COLORCHANGE;
						iFileChanged = TRUE;
						bFilestatusChanged = TRUE;
						iCurrentNibble = 1;
						update_size_change();
					}
					else
					{
						MessageBox (_T("Not enough memory to insert character."), _T("Insertion error:"), MB_OK | MB_ICONERROR);
						return 0;
					}
				}
			}
			return 1;
		}
		else if (iTextEntryMode == CHARS)
		{
			if (FileBuffer.InsertExpandOn(iCurrentByte, 0, 1) == TRUE)
			{
				vChanges.push_back(COLORCHANGE);
				iCurrentNibble = 0;
				iInsertMode = FALSE;
				character (ch);
				iInsertMode = TRUE;
				iCurrentNibble = 0;
				update_size_change ();
			}
			else
			{
				MessageBox (_T("Not enough memory to insert character."), _T("Insertion error:"), MB_OK | MB_ICONERROR);
				return 0;
			}
		}
		return 1;
	}
	else
	{
		if ((iTextEntryMode == BYTES) && ((c >= 'a' && c <= 'f') || (c >= '0' && c <= '9')))
		{
			if (c >= 'a' && c <= 'f')
				x = c - 0x61 + 0x0a;
			else
				x = c - 0x30;
			if (iCurrentNibble == 0)
			{
				FileBuffer[iCurrentByte] = (FileBuffer[iCurrentByte] & 0x0f) | (x << 4);
				vChanges[iCurrentByte] = COLORCHANGE;
			}
			else
			{
				FileBuffer[iCurrentByte] = (FileBuffer[iCurrentByte] & 0xf0) | x;
				vChanges[iCurrentByte] = COLORCHANGE;
			}
			iFileChanged = TRUE;
			bFilestatusChanged = TRUE;
			keydown (VK_RIGHT);
		}
		else if (iTextEntryMode == CHARS)
		{
			//switch (iCharacterSet)
			//{
			//case ANSI_FIXED_FONT:
				FileBuffer[iCurrentByte] = ch;
				vChanges[iCurrentByte] = COLORCHANGE;
				//break;

			//case OEM_FIXED_FONT:
			//	{
			//		char src[2], dst[2];
			//		src[0] = ch;
			//		src[1] = 0;
			//		CharToOem (src, dst);
			//		FileBuffer[iCurrentByte] = dst[0];
			//		vChanges[iCurrentByte] = COLORCHANGE;
			//	}
			//	break;
			//}
			iFileChanged = TRUE;
			bFilestatusChanged = TRUE;
			keydown (VK_RIGHT);
		}
	}
	return 0;
}

int Translhextion::vertical_scroll (int cmd, int pos)
{
	//if ((filename[0] == '\0') || FileBuffer.Length()==0)
	//	return 0;

	//iVerticalScrollInc = 0;
	//switch (cmd)
	//{
	//case SB_TOP:
	//	iCurrentLine = 0;
	//	break;
	//case SB_BOTTOM:
	//	iCurrentLine = iNumlines-1;
	//	break;
	//case SB_LINEUP:
	//	if (iCurrentLine > 0)
	//		iCurrentLine -= 1;
	//	break;
	//case SB_LINEDOWN:
	//	if (iCurrentLine < iNumlines-1)
	//		iCurrentLine += 1;
	//	break;
	//case SB_PAGEUP:
	//	if (iCurrentLine >= cBufferY)
	//		iCurrentLine -= cBufferY;
	//	else
	//		iCurrentLine = 0;
	//	break;
	//case SB_PAGEDOWN:
	//	if (iCurrentLine <= iNumlines-1-cBufferY)
	//		iCurrentLine += cBufferY;
	//	else
	//		iCurrentLine = iNumlines-1;
	//	break;
	//case SB_THUMBTRACK:
	//	iCurrentLine = (int) (pos * ((float)(iNumlines-1)/(float)iVerticalScrollMax));
	//	SetScrollPos (hwndVBar, SB_CTL, pos, TRUE);
	//	if (iCurrentLine > iNumlines-1)
	//		iCurrentLine = iNumlines-1;
	//	if( iNumlines - iCurrentLine < cBufferY )
	//	{
	//		iCurrentLine = ( ( FileBuffer.Upper() + 1 ) / iBytesPerLine ) - ( cBufferY - 1 );
	//		if( iCurrentLine < 0 )
	//			iCurrentLine = 0;
	//	}
	//	repaint();
	//	return 0;
	//default:
	//	break;
	//}
	//iVerticalScrollPos = (int) ((float)iCurrentLine * ((float)iVerticalScrollMax)/(float)(iNumlines-1));
	//SetScrollPos (hwndVBar, SB_CTL, iVerticalScrollPos, TRUE);
	//if (iCurrentLine > iNumlines-1)
	//	iCurrentLine = iNumlines-1;
	//repaint ();
	return 0;
}

int Translhextion::horizontal_scroll (int cmd, int pos)
{
	//if ((filename[0] == '\0') || FileBuffer.Length()==0)
	//	return 0;

	//iHorizontalScrollInc = 0;
	//switch (cmd)
	//{
	//case SB_TOP:
	//	iHorizontalScrollInc = -iHorizontalScrollPos;
	//	break;
	//case SB_BOTTOM:
	//	iHorizontalScrollInc = iHorizontalScrollMax - iHorizontalScrollPos;
	//	break;
	//case SB_LINEUP:
	//	if (iHorizontalScrollPos > 0)
	//		iHorizontalScrollInc = -1;
	//	break;
	//case SB_LINEDOWN:
	//	if (iHorizontalScrollPos < iHorizontalScrollMax)
	//		iHorizontalScrollInc = 1;
	//	break;
	//case SB_PAGEUP:
	//	if (iHorizontalScrollPos >= cxBuffer)
	//		iHorizontalScrollInc = -cxBuffer;
	//	else
	//		iHorizontalScrollInc = -iHorizontalScrollPos;
	//	break;
	//case SB_PAGEDOWN:
	//	if (iHorizontalScrollPos <= iHorizontalScrollMax-cxBuffer)
	//		iHorizontalScrollInc = cxBuffer;
	//	else
	//		iHorizontalScrollInc = iHorizontalScrollMax - iHorizontalScrollPos;
	//	break;
	//case SB_THUMBTRACK:
	//	iHorizontalScrollInc = pos - iHorizontalScrollPos;
	//	break;
	//default:
	//	break;
	//}
	//iHorizontalScrollPos += iHorizontalScrollInc;
	//SetScrollPos (hwndHBar, SB_CTL, iHorizontalScrollPos, TRUE);
	////InvalidateRect (hwnd, NULL, FALSE);
	////UpdateWindow (hwnd);
	//Invalidate(FALSE);
	return 0;
}

#include "MemDC.h"

void Translhextion::DrawFrame(HDC lpDC)
{
	CMemDC memDC(lpDC,*this,true);
	HDC hdc=memDC.GetDC();
	
	//HDC hdc = BeginPaint (hwnd, &ps);
	HideCaret (*this);
	int a, b;
	b = min (iCurrentLine + cBufferY, iNumlines-1);
	iBkColor = PALETTERGB (GetRValue(iBkColorValue),GetGValue(iBkColorValue),GetBValue(iBkColorValue));
	iTextColor = PALETTERGB (GetRValue(iTextColorValue),GetGValue(iTextColorValue),GetBValue(iTextColorValue));
	iTextColorE = PALETTERGB (GetRValue(iTextColorEValue),GetGValue(iTextColorEValue),GetBValue(iTextColorEValue));
	iTextColorO = PALETTERGB (GetRValue(iTextColorOValue),GetGValue(iTextColorOValue),GetBValue(iTextColorOValue));
	SetTextColor (hdc, iTextColor);
	SetBkColor (hdc, iBkColor);
	HPEN pen1 = CreatePen (PS_SOLID, 1, iBkColor);
	HPEN oldpen = (HPEN) SelectObject (hdc, pen1);
	HBRUSH brush1 = CreateSolidBrush (iBkColor);
	HBRUSH oldbrush = (HBRUSH) SelectObject (hdc, brush1);
	if ((b-iCurrentLine+1)*cCharYDim+BORDER_CLIENT_XDIM < cClientYDim-BORDER_CLIENT_XDIM)
		Rectangle (hdc,
			BORDER_CLIENT_XDIM,
			cClientYPos+(b-iCurrentLine+1)*cCharYDim+BORDER_CLIENT_XDIM,
			cClientXDim-BORDER_CLIENT_XDIM,
			cClientYDim-BORDER_CLIENT_XDIM);
	if(!bThingyView)
	{
		Rectangle (hdc,
			((iHorizontalScrollMax+1)-iHorizontalScrollPos)*cCharXDim+BORDER_CLIENT_XDIM,
			BORDER_CLIENT_XDIM+cClientYPos,
			cClientXDim-BORDER_CLIENT_XDIM, cClientYDim-BORDER_CLIENT_XDIM);
	}
	else
	{
		//NOT GREAT BB
		Rectangle (hdc,
			((iHorizontalScrollMax+1)-iHorizontalScrollPos)*cCharXDim+BORDER_CLIENT_XDIM, BORDER_CLIENT_XDIM+cClientYPos,
			cClientXDim-BORDER_CLIENT_XDIM, cClientYDim-BORDER_CLIENT_XDIM);
	}
	SelectObject (hdc, oldpen);
	SelectObject (hdc, oldbrush);
	DeleteObject (pen1);
	DeleteObject (brush1);
	
	HFONT oldfont = (HFONT) SelectObject (hdc, hFont);
	HPEN sep_pen = CreatePen (PS_SOLID, 1, iSepColorValue);
	oldpen = (HPEN) SelectObject (hdc, sep_pen);

	if( Linebuffer.GetSize() < iCharsPerLine )
	{
		if( Linebuffer.SetLength( iCharsPerLine ) )
		{
			Linebuffer.ExpandToSize();
			HBRUSH hbr = CreateSolidBrush( iBookmarkColor );
			if (iUpdateLine == -1)
			{
				for (a = iCurrentLine; a <= b; a++)
					print_line( hdc, a, Linebuffer, hbr );
			}
			else
			{
				print_line( hdc, iUpdateLine, Linebuffer, hbr );
			}
			DeleteObject( hbr );
			SelectObject (hdc, oldpen);
			DeleteObject (sep_pen);
			SelectObject (hdc, oldfont);
			if(!bThingyView)
			{
				invert_char (hdc);
			}
			else
			{
				if (iUpdateLine == -1)
				{
					thingy_view_invert_char (hdc,a);
				}
				else
				{
					thingy_view_invert_char (hdc,iUpdateLine);
				}
				
			}
			draw_border_client_rect (hdc);
			ShowCaret (*this);
			place_cursor ();
			update_window_status ();
			iUpdateLine = -1;
			return;
		}
		else
		{
			Rectangle( hdc, 0, cClientYPos, cClientXDim, cClientYDim );
			RECT r;
			r.top = BORDER_CLIENT_XDIM;
			r.left = BORDER_CLIENT_XDIM+cClientYPos;
			r.right = cClientXDim;
			r.bottom = cClientYDim;
			DrawText( hdc,_T("Error: could not allocate iLine buffer.\nPlease save your changes and restart the program."), -1, &r, DT_LEFT );
		}
		
	}
	else
	{
			HBRUSH hbr = CreateSolidBrush( iBookmarkColor );
			if (iUpdateLine == -1)
			{
				for (a = iCurrentLine; a <= b; a++)
					print_line( hdc, a, Linebuffer, hbr );
			}
			else
			{
				print_line( hdc, iUpdateLine, Linebuffer, hbr );
			}
			DeleteObject( hbr );
			SelectObject (hdc, oldpen);
			DeleteObject (sep_pen);
			SelectObject (hdc, oldfont);
			if(!bThingyView)
			{
				invert_char (hdc);
			}
			else
			{
				if (iUpdateLine == -1)
				{
					thingy_view_invert_char (hdc,a);
				}
				else
				{
					thingy_view_invert_char (hdc,iUpdateLine);
				}
			}
			draw_border_client_rect (hdc);
			ShowCaret (*this);
			place_cursor ();
			update_window_status ();
			iUpdateLine = -1;
	}
}

int Translhextion::paint()
{
	PAINTSTRUCT ps;
	HDC hdc=BeginPaint (*this, &ps);

	DrawFrame(hdc);

	EndPaint (*this, &ps);

	return 0;
}

int Translhextion::destroy_window ()
{
	return 0;
}

void Translhextion::update_window_status()
{
	GString cBuf;

	if(!filename.IsEmpty())
	{
		if (bFilestatusChanged)
		{
			cBuf.Format(_T("[%s%s]%s - %s"), (LPCTSTR)filename, iFileChanged ? _T("*") : _T(""), bPartialOpen ? _T(" /P") : _T(""), sName);
			::SetWindowText (*this, cBuf);
			bFilestatusChanged = FALSE;
		}
		if (bSelected == TRUE)
		{
			if (iEndOfSelection >= iStartOfSelection)
			{
				//if(iOffsetMode == LOROM)
				//	cBuf.Format(_T("Selected: Offset %d=0x%X to %d=0x%X (%d byte(s))"), iStartOfSelection, toLOROM(iStartOfSelection),
				//	iEndOfSelection, toLOROM(iEndOfSelection), iEndOfSelection-iStartOfSelection+1);
				//else if(iOffsetMode == HIROM)
				//	cBuf.Format(_T("Selected: Offset %d=0x%X to %d=0x%X (%d byte(s))"), iStartOfSelection, toHIROM(iStartOfSelection),
				//	iEndOfSelection, toHIROM(iEndOfSelection), iEndOfSelection-iStartOfSelection+1);
				//else
					cBuf.Format(_T("Selected: Offset %d=0x%X to %d=0x%X (%d byte(s))"), iStartOfSelection, iStartOfSelection,
					iEndOfSelection, iEndOfSelection, iEndOfSelection-iStartOfSelection+1);

			}
			else
			{
				//if(iOffsetMode == LOROM)
				//	cBuf.Format(_T("Selected: Offset %d=0x%X to %d=0x%X (%d byte(s))"), iEndOfSelection, toLOROM(iEndOfSelection),
				//	iStartOfSelection, toLOROM(iStartOfSelection), iStartOfSelection-iEndOfSelection+1);
				//else if(iOffsetMode == HIROM)
				//	cBuf.Format(_T("Selected: Offset %d=0x%X to %d=0x%X (%d byte(s))"), iEndOfSelection, toHIROM(iEndOfSelection),
				//	iStartOfSelection, toHIROM(iStartOfSelection), iStartOfSelection-iEndOfSelection+1);
				//else
					cBuf.Format(_T("Selected: Offset %d=0x%X to %d=0x%X (%d byte(s))"), iEndOfSelection, iEndOfSelection,
					iStartOfSelection, iStartOfSelection, iStartOfSelection-iEndOfSelection+1);
			}
			SendMessage (hwndStatusBar, SB_SETTEXT, 0, (LPARAM) (LPCTSTR)cBuf);
		}
		else 
		{
			//if(iOffsetMode == LOROM)	
			//	cBuf.Format(_T("Offset %d=0x%X"), iCurrentByte, toLOROM(iCurrentByte));
			//else if(iOffsetMode == HIROM)
			//	cBuf.Format(_T("Offset %d=0x%X"), iCurrentByte, toHIROM(iCurrentByte));
			//else
				cBuf.Format(_T("Offset %d=0x%X"), iCurrentByte, iCurrentByte);	
			int wordval, longval;
			GString buf2;
			if (FileBuffer.Length()-iCurrentByte > 0)
			{
				int i;
				cBuf+=_T("   Bits=");
				unsigned char zzz=FileBuffer[iCurrentByte];
				for(i=0;i<8;i++) buf2+=(zzz>>i)&0x1 ? '1':'0';
				for(i=0;i<4;i++)
				{
					TCHAR temp=buf2[i];
					buf2.SetAt(i,buf2[7-i]);
					buf2.SetAt(7-i,temp);
					//sswap(buf2[i],buf2[7-i]);
				}
				//buf2[8]='\0';
				cBuf+=buf2;
				if(bTableLoaded && bTableActive)
				{
					bool oldbmark = bByteMark;
					int wherebyte = 0;
					bByteMark = false;
					std::vector<_tstring> temp;
					temp = vEmpty;
					if(iCurrentByte-2 >= 0)
						temp.push_back(hex_char(FileBuffer[iCurrentByte-2]));
					if(iCurrentByte-1 >= 0)
						temp.push_back(hex_char(FileBuffer[iCurrentByte-1]));
					temp.push_back(hex_char(FileBuffer[iCurrentByte]));
					wherebyte = temp.size()-1;
					if(iCurrentByte + 1 < FileBuffer.Length())
						temp.push_back(hex_char(FileBuffer[iCurrentByte+1]));
					if(iCurrentByte + 2 < FileBuffer.Length())
						temp.push_back(hex_char(FileBuffer[iCurrentByte+2]));
					bSplitMultiByte = false;
					table.translate(temp);
					bSplitMultiByte = true;
					if(temp[wherebyte] == L"")
					{
						if(wherebyte + 1 < (int)temp.size() && temp[wherebyte+1] == L"")
						{
							if(wherebyte - 1 >= 0)
							{
								cBuf+=_T("   Table=");
								cBuf+=temp[wherebyte-1].c_str();
							}
							else
							{
								cBuf+=_T("   Table=");
								cBuf+=_T("ERROR!");
							}
						}
						else if(wherebyte - 1 >= 0 && temp[wherebyte-1] == L"")
						{
							if(wherebyte - 2 >= 0)
							{
								cBuf+=_T("   Table=");
								cBuf+=temp[wherebyte-2].c_str();
							}
							else
							{
								cBuf+=_T("   Table=");
								cBuf+=_T("ERROR!");
							}
						}
						else if(wherebyte - 1 >= 0)
						{
							cBuf+=_T("   Table=");
							cBuf+=temp[wherebyte-1].c_str();
						}
						else
						{
							cBuf+=_T("   Table=");
							cBuf+=_T("ERROR!");
						}
					}
					else
					{
						cBuf+=_T("   Table=");
						cBuf+=temp[wherebyte].c_str();
					}
					bByteMark = oldbmark;
				}
			}
			cBuf+=_T("\t");
			if (bUnsignedView) 
			{
				
				if (iBinaryMode == LITTLE_ENDIAN)
				{
					if (FileBuffer.Length ()-iCurrentByte >= 1)
					{
						buf2.Format(_T("\tUnsigned: B:%u"), (unsigned int) FileBuffer[iCurrentByte]);
						cBuf+=buf2;
					}
					else
					{
						buf2=_T("\tEND");
						cBuf+=buf2;
					}
					if (FileBuffer.Length ()-iCurrentByte >= 2)
					{
						wordval = (FileBuffer[iCurrentByte+1] << 8) | FileBuffer[iCurrentByte];
						buf2.Format(_T(",W:%u"), (unsigned int) wordval);
						cBuf+=buf2;
					}
					if (FileBuffer.Length ()-iCurrentByte >= 4)
					{
						longval = wordval | (((FileBuffer[iCurrentByte + 3] << 8) | FileBuffer[iCurrentByte + 2]) << 16);
						buf2.Format(_T(",L:%u"), (unsigned int) longval);
						cBuf+=buf2;
					}
				}
				else
				{
					if (FileBuffer.Length ()-iCurrentByte >= 1)
					{
						buf2.Format(_T("\tUnsigned: B:%u"), (unsigned int) FileBuffer[iCurrentByte]);
						cBuf+=buf2;
					}
					else
					{
						buf2=_T("\tEND");
						cBuf+=buf2;
					}
					if (FileBuffer.Length ()-iCurrentByte >= 2)
					{
						wordval = (FileBuffer[iCurrentByte] << 8) | FileBuffer[iCurrentByte+1];
						buf2.Format(_T(",W:%u"), (unsigned int) wordval);
						cBuf+=buf2;
					}
					if (FileBuffer.Length ()-iCurrentByte >= 4)
					{
						longval = (wordval<<16) | (FileBuffer[iCurrentByte+2]<<8) | (FileBuffer[iCurrentByte+3]);
						buf2.Format(_T(",L:%u"), (unsigned int) longval);
						cBuf+=buf2;
					}
				}
			}
			else 
			{
				if (iBinaryMode == LITTLE_ENDIAN)
				{
					if (FileBuffer.Length ()-iCurrentByte >= 1)
					{
						buf2.Format(_T("\tSigned: B:%d"), (int) (signed char) FileBuffer[iCurrentByte]);
						cBuf+=buf2;
					}
					else
					{
						buf2=_T("\tEND");
						cBuf+=buf2;
					}
					
					if (FileBuffer.Length ()-iCurrentByte >= 2)
					{
						
						wordval = (FileBuffer[iCurrentByte + 1] << 8) | FileBuffer[iCurrentByte];
						buf2.Format(_T(",W:%d"), (int) (signed short) wordval);
						cBuf+=buf2;
					}
					if (FileBuffer.Length ()-iCurrentByte >= 4)
					{
						longval = wordval | (((FileBuffer[iCurrentByte + 3] << 8) | FileBuffer[iCurrentByte + 2]) << 16);
						buf2.Format(_T(",L:%d"), (signed int) longval);
						cBuf+=buf2;
					}
				}
				else
				{
					if (FileBuffer.Length ()-iCurrentByte >= 1)
					{
						buf2.Format(_T("\tSigned: B:%d"), (signed char) FileBuffer[iCurrentByte]);
						cBuf+=buf2;
					}
					else
					{
						buf2.Format(_T("\tEND"));
						cBuf+=buf2;
					}
					
					if (FileBuffer.Length ()-iCurrentByte >= 2)
					{
						
						wordval = (FileBuffer[iCurrentByte] << 8) | FileBuffer[iCurrentByte+1];
						buf2.Format(_T(",W:%d"), (int) (signed short) wordval);
						cBuf+=buf2;
					}
					if (FileBuffer.Length ()-iCurrentByte >= 4)
					{
						
						longval = (wordval<<16) | (FileBuffer[iCurrentByte+2]<<8) | (FileBuffer[iCurrentByte+3]);
						buf2.Format(_T(",L:%d"), (signed int) longval);
						cBuf+=buf2;
					}
				}
			}
			SendMessage (hwndStatusBar, SB_SETTEXT, 0, (LPARAM) (LPCTSTR)cBuf);

			
			switch (iCharacterSet)
			{
			//case ANSI_FIXED_FONT:
			//	cBuf=_T("\tANSI");
			//	break;

			//case OEM_FIXED_FONT:
			//	cBuf=_T("\tOEM");
			//	break;
			case ENCODING_BYTE:
				cBuf=_T("\tBYTE");
				break;

			case ENCODING_WIDE:
				cBuf=_T("\tWIDE");
				break;
			}

			if( bReadOnly )
			{
				buf2=_T(" / READ");
				cBuf+=buf2;
			}
			else if( iInsertMode )
			{
				buf2=_T(" / INS");
				cBuf+=buf2;
			}
			else
			{
				buf2=_T(" / OVR");
				cBuf+=buf2;
			}
			if (iBinaryMode == LITTLE_ENDIAN)
			{
				buf2=_T(" / L"); 
				cBuf+=buf2;
			}
			else if (iBinaryMode == BIG_ENDIAN)
			{
				buf2=_T(" / B"); 
				cBuf+=buf2;
			}
			//if(iOffsetMode == LOROM)
			//{
			//	buf2=_T(" / LOROM"); 
			//	cBuf+=buf2;
			//}
			//else if(iOffsetMode == HIROM)
			//{
			//	buf2=_T(" / HIROM"); 
			//	cBuf+=buf2;
			//}
			SendMessage (hwndStatusBar, SB_SETTEXT, 1, (LPARAM) (LPCTSTR)cBuf);
			
			
			cBuf.Format(_T("\tSize: %u"), FileBuffer.Length ());
			SendMessage (hwndStatusBar, SB_SETTEXT, 2, (LPARAM) (LPCTSTR)cBuf);
		}
	}
	else
	{
		::SetWindowText (*this, sName);
		SendMessage (hwndStatusBar, WM_SETTEXT, 0, (LPARAM) _T("No file loaded"));
	}
}

void Translhextion::place_cursor ()
{
	if (bSelected)
	{
		SetCaretPos (-cCharXDim, -cCharYDim+cClientYPos);
		return;
	}
	if(bHideHex)
		return;
	int iCaretLine = iCurrentByte / iBytesPerLine,
		iBottomLine = iCurrentLine + cBufferY - 1;

	switch (iTextEntryMode)	
	{
	case CHARS:
		if (iCaretLine >= iCurrentLine && iCaretLine <= iBottomLine && !filename.IsEmpty())
		{
			int y = iCaretLine - iCurrentLine;
			int x = 0;
			//if(!bThingyView)
			//{
				x = iOffsetLength+iByteSpace+iBytesPerLine*3+iCharSpace - iHorizontalScrollPos + (iCurrentByte%iBytesPerLine);
			//}
			//else
			//{
			//	x = iOffsetLength+iByteSpace+iBytesPerLine*2 + iMaxCharLine +iCharSpace - iHorizontalScrollPos + (iCurrentByte%iBytesPerLine);
			//}
			SetCaretPos (BORDER_CLIENT_XDIM + x*cCharXDim, BORDER_CLIENT_XDIM + y*cCharYDim+cClientYPos);
		}
		else
			SetCaretPos (-cCharXDim, -cCharYDim + cClientYPos);
		break;
	case BYTES:
		
		if (iCaretLine >= iCurrentLine && iCaretLine <= iBottomLine && !filename.IsEmpty())
		{
			int y = iCaretLine - iCurrentLine;
			int	x = iOffsetLength+iByteSpace + (iCurrentByte%iBytesPerLine)*3 - iHorizontalScrollPos + iCurrentNibble;
			SetCaretPos (BORDER_CLIENT_XDIM + x*cCharXDim, BORDER_CLIENT_XDIM + y*cCharYDim + cClientYPos);
		}
		else
			SetCaretPos (-cCharXDim, -cCharYDim+cClientYPos);
	}
}

int Translhextion::repaint( int iLine )
{
	HideCaret( *this );
	iUpdateLine = iLine;
	InvalidateRect( *this, NULL, FALSE );
	UpdateWindow( *this );
	ShowCaret( *this );
	return 0;
}

void Translhextion::clear_all ()
{
	iOffsetLength = 8;
	iByteSpace = 2;
	iBytesPerLine = 16;
	iCharSpace = 1;
	//if(!bThingyView)
	//{
		iCharsPerLine = iOffsetLength + iByteSpace + iBytesPerLine*3 + iCharSpace + iBytesPerLine;
	//}
	//else
	//{
	//	iCharsPerLine = iOffsetLength + iByteSpace + iBytesPerLine*2 + iMaxCharLine + iCharSpace + iBytesPerLine;
	//}
	FileBuffer.Reset ();
	vChanges = vEmpty;
	vHighlights = vEmpty;
	vDTEs = vEmpty;
	filename.Empty();
	iVerticalScrollMax = 0;
	iVerticalScrollPos = 0;
	iVerticalScrollInc = 0;
	iHorizontalScrollMax = 0;
	iHorizontalScrollPos = 0;
	iHorizontalScrollInc = 0;
	iCurrentLine = 0;
	iCurrentByte = 0;
	iCurrentNibble = 0;
}

void Translhextion::update_vertical_scrollbar ()
{
	//iVerticalScrollPos = (int) ((float)iCurrentLine * ((float)iVerticalScrollMax)/(float)(iNumlines-1));
	//SetScrollPos (hwndVBar, SB_CTL, iVerticalScrollPos, TRUE);
}

void Translhextion::update_horizontal_scrollbar ()
{
	//SetScrollPos (hwndHBar, SB_CTL, iHorizontalScrollPos, TRUE);
}

void Translhextion::invert_char (HDC hdc)
{
	if( bDontMarkCurrentPos )
		return;
	if(bHideHex)
		return;

	if (bSelected)
	{
		SetCaretPos (-cCharXDim, -cCharYDim);
		return;
	}

	int retrieved_device_context = FALSE;
	if (hdc == 0)
	{
		hdc = GetDC (*this);
		retrieved_device_context = TRUE;		
	}

	int iCharCoordinate;
	RECT r;
	switch (iTextEntryMode)
	{
	case CHARS:
		iCharCoordinate = iOffsetLength + iByteSpace + (iCurrentByte%iBytesPerLine)*3 - iHorizontalScrollPos;
		r.left = BORDER_CLIENT_XDIM + iCharCoordinate * cCharXDim;
		r.top = BORDER_CLIENT_XDIM + (iCurrentByte/iBytesPerLine-iCurrentLine)*cCharYDim;
		r.right = BORDER_CLIENT_XDIM + r.left + 2*cCharXDim;
		r.bottom = BORDER_CLIENT_XDIM + (iCurrentByte/iBytesPerLine-iCurrentLine+1)*cCharYDim;
		InvertRect (hdc, &r);
		break;
	case BYTES:
		if(!bThingyView)
		{
			iCharCoordinate = iOffsetLength + iByteSpace + iBytesPerLine*3 + iCharSpace
				+ (iCurrentByte % iBytesPerLine) - iHorizontalScrollPos;
			r.left = BORDER_CLIENT_XDIM + iCharCoordinate * cCharXDim;
			r.top = BORDER_CLIENT_XDIM + (iCurrentByte/iBytesPerLine-iCurrentLine)*cCharYDim;
			r.right = BORDER_CLIENT_XDIM + (iCharCoordinate+1)*cCharXDim;
			r.bottom = BORDER_CLIENT_XDIM + (iCurrentByte/iBytesPerLine-iCurrentLine+1)*cCharYDim;
			InvertRect (hdc, &r);
		}
		else
		{//comeback
		//	iCharCoordinate = iOffsetLength + iByteSpace + iBytesPerLine*3 + iCharSpace
		//		+ (iCurrentByte % iBytesPerLine) - iHorizontalScrollPos;
		//	r.left = BORDER_CLIENT_XDIM + iCharCoordinate * cCharXDim;
		//	r.top = BORDER_CLIENT_XDIM + (iCurrentByte/iBytesPerLine-iCurrentLine)*cCharYDim;
		//	r.right = BORDER_CLIENT_XDIM + (iCharCoordinate+1)*cCharXDim;
		//	r.bottom = BORDER_CLIENT_XDIM + (iCurrentByte/iBytesPerLine-iCurrentLine+1)*cCharYDim;
		//	InvertRect (hdc, &r);
		}
		break;
		
	}

	if (retrieved_device_context)
		ReleaseDC (*this, hdc);
}

void Translhextion::thingy_view_invert_char (HDC hdc, int iLine)
{
	if( bDontMarkCurrentPos )
		return;
	if(bHideHex)
		return;
	if (bSelected)
	{
		SetCaretPos (-cCharXDim, -cCharYDim);
		return;
	}
	string output;
	if (iLine < iCurrentLine || iLine > iCurrentLine + cBufferY)
		return;
	int iStartPos = iLine * iBytesPerLine, iEndPos, i = 0, m;
	if( iStartPos > FileBuffer.Upper() + 1 )
	{
		return;
	}
	
	if (iStartPos+iBytesPerLine > FileBuffer.Length ())
	{
		iEndPos = FileBuffer.Upper()+1;
	}
	else
	{
		iEndPos = iStartPos+iBytesPerLine-1;
	}
	if( iEndPos < iStartPos )
	{
		iEndPos = iStartPos;
	}
	m = iOffsetLength+iByteSpace; 
	//vPLineBuf = vEmpty;
	vPLineBuf.clear();
	_tstring highlight;
	for(i = iStartPos;(i + 2 <FileBuffer.Length() && i<=iCurrentByte + 2);i++)
	{
		vPLineBuf.push_back(whex_char(FileBuffer[i]));
	}
	if(vPLineBuf.size() >= 3)
	{
		_tstring output;
		output = L"";
		int j = 0;
		bool oldbytemark = bByteMark;
		bByteMark = false;
		bSplitMultiByte = false;
		table.translate(vPLineBuf);
		bByteMark = oldbytemark;
		bSplitMultiByte = true;
		assert(vPLineBuf.size() > 0);
		vPLineBuf.pop_back();
		assert(vPLineBuf.size() > 0);
		vPLineBuf.pop_back();
		if(vPLineBuf.size() >= 3 && vPLineBuf[vPLineBuf.size() - 1] == L"")
		{
			if(vPLineBuf[vPLineBuf.size()-2] == L"")
			{
				highlight = vPLineBuf[vPLineBuf.size()-3];
				assert(vPLineBuf.size() > 0);
				vPLineBuf.pop_back();
				assert(vPLineBuf.size() > 0);
				vPLineBuf.pop_back();
				assert(vPLineBuf.size() > 0);
				vPLineBuf.pop_back();
				j++;
				j++;
			}
			else
			{
				highlight = vPLineBuf[vPLineBuf.size()-2];
				assert(vPLineBuf.size() > 0);
				vPLineBuf.pop_back();
				assert(vPLineBuf.size() > 0);
				vPLineBuf.pop_back();
				j++;
			}
		}
		else if(vPLineBuf.size() >= 2 && vPLineBuf[vPLineBuf.size()-1] == L"")
		{
			highlight = vPLineBuf[vPLineBuf.size()-2];
			assert(vPLineBuf.size() > 0);
			vPLineBuf.pop_back();
			assert(vPLineBuf.size() > 0);
			vPLineBuf.pop_back();
			j++;
		}
		else
		{
			highlight = vPLineBuf[vPLineBuf.size()-1];
			assert(vPLineBuf.size() > 0);
			vPLineBuf.pop_back();
		}
		if(highlight == L"\n")
		{
			highlight = L"*";
		}
		else if(highlight.substr(1,3) == L"END")
		{
			highlight = L"\\";
		}
		else if(highlight.substr(0,1) == sByteOpen && highlight.length() == 4)
		{
			highlight = L"#";
		}
		else if(highlight.substr(0,1) == sByteOpen)
		{
			highlight = highlight.substr(1,highlight.length()-2);
		}
		int i = 0;
		for(i = 0;i<(int)vPLineBuf.size();i++)
		{
			if(vPLineBuf[i] == L"\n")
			{
				output += L"*";
			}
			else if(vPLineBuf[i].length() >= 4 && vPLineBuf[i].substr(1,3) == L"END")
			{
				output += L"\\";
			}
			else if(vPLineBuf[i].substr(0,1) == sByteOpen && vPLineBuf[i].length() == 4)
			{
				output += L"#";
			}
			else
			{
				if(vPLineBuf[i].substr(0,1) == sByteOpen)
				{
					output += vPLineBuf[i].substr(1,vPLineBuf[i].length()-2);
				}
				else
				{	
					if(bJapanese && vPLineBuf[i].length() == 2)
					{
						_tstring hex = hex_char(vPLineBuf[i][0]) + hex_char(vPLineBuf[i][1]);
						long code = dualbyteindex(hex);
						int ascii = -1;
						if(bJPShift)
						{
							ascii = jpfont_shift(code);
						}
						else
						{
							ascii = (TCHAR)code;
							//ascii = jpfont_euc(code);
						}
						if(ascii != -1)
						{
							vPLineBuf[i] = L"";
							vPLineBuf[i] += (unsigned char) ascii;
							vPLineBuf[i] += (unsigned char) ' ';
							output += vPLineBuf[i];
						}
						else
						{
							output += vPLineBuf[i]; 
						}
						
					}
					else if(bJapanese && vPLineBuf[i].length() == 4)
					{
						_tstring hex = hex_char(vPLineBuf[i][0]) + hex_char(vPLineBuf[i][1]);
						long code1 = dualbyteindex(hex);
						hex = hex_char(vPLineBuf[i][2]) + hex_char(vPLineBuf[i][3]);
						long code2 = dualbyteindex(hex);
						int ascii = -1;
						int ascii2 = -1;
						if(bJPShift)
						{
							ascii = jpfont_shift(code1);
							ascii2 = jpfont_shift(code2);
						}
						else
						{
							ascii = code1;
							ascii2 = code2;
							//ascii = jpfont_euc(code1);
							//ascii2 = jpfont_euc(code2);
						}
						if(ascii != -1)
						{
							vPLineBuf[i] = L"";
							vPLineBuf[i] += (unsigned char) ascii;
							vPLineBuf[i] += (unsigned char) ' ';
							if(ascii2 != -1)
							{
								vPLineBuf[i] += (unsigned char) ascii2;
								vPLineBuf[i] += (unsigned char) ' ';
							}
							output += vPLineBuf[i];
						}
						else
						{
							output += vPLineBuf[i]; 
						}
						
					}
					else
					{
						output += vPLineBuf[i]; 
					}
				}
			}
		}
		i = i + j;
		int retrieved_device_context = FALSE;
		if (hdc == 0)
		{
			hdc = GetDC (*this);
			retrieved_device_context = TRUE;		
		}
	
		int iCharCoordinate;
		RECT r;
		switch (iTextEntryMode)
		{
		case CHARS:
			iCharCoordinate = iOffsetLength + iByteSpace + (iCurrentByte%iBytesPerLine)*3 - iHorizontalScrollPos;
			r.left = BORDER_CLIENT_XDIM + iCharCoordinate * cCharXDim;
			r.top = BORDER_CLIENT_XDIM + (iCurrentByte/iBytesPerLine-iCurrentLine)*cCharYDim;
			r.right = BORDER_CLIENT_XDIM + r.left + 2*cCharXDim;
			r.bottom = BORDER_CLIENT_XDIM + (iCurrentByte/iBytesPerLine-iCurrentLine+1)*cCharYDim;
			InvertRect (hdc, &r);
			break;
		case BYTES:
			iCharCoordinate = iOffsetLength + iByteSpace + iBytesPerLine*3 + iCharSpace
				+ (iCurrentByte % iBytesPerLine) + (output.length()-i) - iHorizontalScrollPos;
			r.left = BORDER_CLIENT_XDIM + iCharCoordinate * cCharXDim;
			r.top = BORDER_CLIENT_XDIM + (iCurrentByte/iBytesPerLine-iCurrentLine)*cCharYDim;
			r.right = BORDER_CLIENT_XDIM + (iCharCoordinate+highlight.length())*cCharXDim;
			r.bottom = BORDER_CLIENT_XDIM + (iCurrentByte/iBytesPerLine-iCurrentLine+1)*cCharYDim;
			InvertRect (hdc, &r);
			break;
		}
	
		if (retrieved_device_context)
			ReleaseDC (*this, hdc);
	}
}

void Translhextion::print_line (HDC hdc, int iLine, TCHAR* ucLineBuf, HBRUSH hbr )
{
	// clear entire line
	//RECT rClient;
	//GetClientRect(hwnd,&rClient);
	//rClient.left+=BORDER_CLIENT_XDIM;
	//rClient.right-=BORDER_CLIENT_XDIM;
	//rClient.top=cClientYPos + BORDER_CLIENT_XDIM + ( iLine - iCurrentLine ) * cCharYDim;
	//rClient.bottom=rClient.top+cCharYDim;
	//FillRect(hdc,&rClient,(HBRUSH)CreateSolidBrush(RGB(255,255,255)));

	_tstring output;
	int totallength = 0;
	vector<int> vAsciiLengths;
	if (iLine < iCurrentLine || iLine > iCurrentLine + cBufferY)
		return;
	int iStartPos = iLine * iBytesPerLine, iEndPos, i = 0, m;
	TCHAR cBuf[80], c;

	if( iStartPos > FileBuffer.Upper() + 1 )
	{
		return;
	}

	_stprintf (cBuf, _T("%%%d.%dX"), iOffsetLength, iOffsetLength);

	for (m=0; m<iByteSpace; m++)
		cBuf[5+m] = ' ';
	cBuf[5+m] = '\0';
	//if(iOffsetMode == LOROM)
	//	_stprintf (ucLineBuf, cBuf, toLOROM(iStartPos));
	//else if(iOffsetMode == HIROM)
	//	_stprintf (ucLineBuf, cBuf, toHIROM(iStartPos));
	//else
		_stprintf (ucLineBuf, cBuf, iStartPos);
	if (iStartPos+iBytesPerLine > FileBuffer.Length ())
	{
		iEndPos = FileBuffer.Upper()+1;
	}
	else
	{
		iEndPos = iStartPos+iBytesPerLine-1;
	}
	if( iEndPos < iStartPos )
	{
		iEndPos = iStartPos;
	}
	m = iOffsetLength+iByteSpace; 
	_tstring dtile;
	for (i=iStartPos; i<=iEndPos; i++)
	{
		if (i == FileBuffer.Length())
		{
			ucLineBuf[m++] = '_';
			ucLineBuf[m++] = '_';
			ucLineBuf[m++] = ' ';
		}
		else
		{
			char temp;
			c = (FileBuffer[i] >> 4);
			temp = (char) c;
			_strupr(&temp);
			c = (int) temp;
			if( c < 10 )
				c += '0';
			else
				c = c - 10 + 'A';
			ucLineBuf[m++] = c;
			c = (FileBuffer[i] & 0x0f);
			if( c < 10 )
				c += '0';
			else
				c = c - 10 + 'A';
			ucLineBuf[m++] = c;
			ucLineBuf[m++] = ' ';
			//for(vu = 0;vu<vHighlights.size();vu++)
			//{  
			if(vTableOut[(unsigned char) FileBuffer[i]].length() == 2)
			{
				//if(vChanges[i] != COLORCHANGE)
				//	vChanges[i] = COLORDTE;
				vDTEs[i] = COLORDTE;
			}
			//if(vChanges[i] == COLORHIGHLIGHT)
			//{
			//	vChanges[i] = COLORNORMAL;
			//}
			if(bHighlight)
			{
				dtile = L"";
				if(i + 1 < (int)vChanges.size())
				{
					dtile += (unsigned char) FileBuffer[i];
					dtile += (unsigned char) FileBuffer[i+1];
					if(vTwoByteHighlightTable[dualtileindex(dtile)] == L"1")
					{
						//if(vChanges[i] != COLORCHANGE)
						//	vChanges[i] = COLORHIGHLIGHT;
						//if(vChanges[i + 1] != COLORCHANGE)
						//	vChanges[i + 1] = COLORHIGHLIGHT;
						vHighlights[i] = COLORHIGHLIGHT;
						vHighlights[i + 1] = COLORHIGHLIGHT;
					}
					else if(vTwoByteHighlightTable[(unsigned char) FileBuffer[i]] == L"1")
					{
						vHighlights[i] = COLORHIGHLIGHT;
					}
				}
				else
				{
					if(vTwoByteHighlightTable[(unsigned char) FileBuffer[i]] == L"1")
					{
						//if(vChanges[i] != COLORCHANGE)
						//	vChanges[i] = COLORHIGHLIGHT;
						vHighlights[i] = COLORHIGHLIGHT;
					}
				}
			}
			//}
		}
	}
	if (iEndPos-iStartPos < iBytesPerLine-1)
	{
		for (i=0; i<iBytesPerLine-1-(iEndPos-iStartPos); i++)
		{
			ucLineBuf[m++] = ' ';
			ucLineBuf[m++] = ' ';
			ucLineBuf[m++] = ' ';
		}
	}

	for (i=0; i<iCharSpace; i++)
		ucLineBuf[m++] = ' ';
	
	unsigned char * temp;
	int k = 0;
	if(!bThingyView)
	{
		for (i=iStartPos; i<=iEndPos; i++)
		{
			temp = &(FileBuffer[i]);
			if (i == FileBuffer.Length())
			{
				ucLineBuf[m++] = ' ';
			}
			//else if (iCharacterSet == OEM_FIXED_FONT && FileBuffer[i]!=0)
			//{
			//	ucLineBuf[m++] = *temp;
			//}
			else if ((FileBuffer[i]>=32 && FileBuffer[i]<=126) || (FileBuffer[i]>=160 && FileBuffer[i]<=255) || (FileBuffer[i]>=145 && FileBuffer[i]<=146))
			{
				ucLineBuf[m++] = *temp;
			}
			else
			{
				ucLineBuf[m++] = '.';
			}
		}

	}
	else
	{
		std::vector<_tstring> dsize(iEndPos - iStartPos + 1);
		vPLineBuf = dsize;
		dsize = vEmpty;
		for (i=iStartPos; i<=iEndPos; i++)
		{
			if (i == FileBuffer.Length())
			{
				;
			}
			else
			{
				vPLineBuf[i - iStartPos] = hex_char(FileBuffer[i]);
			}
		}
		bool oldbytemark = bByteMark;
		bByteMark = false;
		bSplitMultiByte = false;
		table.translate(vPLineBuf);
		bSplitMultiByte = true;
		bByteMark = oldbytemark;
		if(i == FileBuffer.Length())
		{
			vPLineBuf.push_back(L" ");
		}
		output = L"";
		vector<int> dsize2(vPLineBuf.size());
		vAsciiLengths = dsize2;
		dsize2 = viEmpty;

		// draw a line?
		for(i = 0;i<(int)vPLineBuf.size();i++)
		{
			if(vPLineBuf[i] == L"\n")
			{
				output += L"*";
				vAsciiLengths[i] = 1;
			}
			else if(vPLineBuf[i].length() >= 4 && vPLineBuf[i].substr(1,3) == L"END")
			{
				output += L"\\";
				vAsciiLengths[i] = 1;
			}
			else if(vPLineBuf[i].substr(0,1) == sByteOpen && vPLineBuf[i].length() == 4) //what about double bytes that translate to {xx}? triples?
			{
				output += L"#";
				vAsciiLengths[i] = 1;
			}
			else
			{
				if(vPLineBuf[i].substr(0,1) == sByteOpen)
				{
					output += vPLineBuf[i].substr(1,vPLineBuf[i].length()-2); 
					vAsciiLengths[i] = vPLineBuf[i].length()-2;
				}
				else
				{
					if(bJapanese && vPLineBuf[i].length() == 2)
					{
						_tstring hex = hex_char(vPLineBuf[i][0]) + hex_char(vPLineBuf[i][1]);
						long code = dualbyteindex(hex);
						TCHAR ascii = -1;

						// decode sjis
						if(bJPShift)
						{
							ascii = jpfont_shift(code);
						}
						// copy utf16
						else
						{
							ascii = (TCHAR)code;
							//ascii = jpfont_euc(code);
						}

						if(ascii != -1)
						{
							vPLineBuf[i] = L"";
							vPLineBuf[i] += ascii;
							output += vPLineBuf[i];
						}
						else
						{
							output += vPLineBuf[i]; 
						}
						
					}
					else if(bJapanese && vPLineBuf[i].length() == 4)
					{
						_tstring hex = hex_char(vPLineBuf[i][0]) + hex_char(vPLineBuf[i][1]);
						long code1 = dualbyteindex(hex);
						hex = hex_char(vPLineBuf[i][2]) + hex_char(vPLineBuf[i][3]);
						long code2 = dualbyteindex(hex);
						TCHAR ascii = -1;
						TCHAR ascii2 = -1;
						if(bJPShift)
						{
							ascii = jpfont_shift(code1);
							ascii2 = jpfont_shift(code2);
						}
						else
						{
							ascii = (TCHAR)code1;
							ascii2 = (TCHAR)code2;
							//ascii = jpfont_euc(code1);
							//ascii2 = jpfont_euc(code2);
						}
						if(ascii != -1)
						{
							vPLineBuf[i] = L"";
							vPLineBuf[i] += ascii;
							//vPLineBuf[i] += ' ';
							if(ascii2 != -1)
							{
								vPLineBuf[i] += ascii2;
								//vPLineBuf[i] += ' ';
							}
							output += vPLineBuf[i];
						}
						else
						{
							output += vPLineBuf[i]; 
						}
						
					}
					else
					{
						output += vPLineBuf[i]; 
					}
					vAsciiLengths[i] = vPLineBuf[i].length();
				}
			}
		}
		if((int)output.length() < iMaxCharLine)
		{
			i = output.length();
			if(bHideHex)
				i = i - 15;
			for(i = i; i < iMaxCharLine;i++)
				output += L" ";
		}
		else
		{//NOT GREAT BB
			iLastMaxCharLine = iMaxCharLine;
			iMaxCharLine = 2 * output.length();
		}
	}
	if (iEndPos-iStartPos < iBytesPerLine-1)
		for (i=0; i<iBytesPerLine-1-(iEndPos-iStartPos); i++)
			ucLineBuf[m++] = ' ';
	
	
	int iLineLen = m; 

	iBkColor = PALETTERGB (GetRValue(iBkColorValue),GetGValue(iBkColorValue),GetBValue(iBkColorValue));
	iTextColor = PALETTERGB (GetRValue(iTextColorValue),GetGValue(iTextColorValue),GetBValue(iTextColorValue));
	iTextColorE = PALETTERGB (GetRValue(iTextColorEValue),GetGValue(iTextColorEValue),GetBValue(iTextColorEValue));
	iTextColorO = PALETTERGB (GetRValue(iTextColorOValue),GetGValue(iTextColorOValue),GetBValue(iTextColorOValue));
	SetTextColor (hdc, iTextColor);
	SetBkColor (hdc, iBkColor);

	if( iHorizontalScrollPos < iOffsetLength + iByteSpace )
	{
		TextOut( hdc,
			BORDER_CLIENT_XDIM,
			cClientYPos + BORDER_CLIENT_XDIM + ( iLine - iCurrentLine ) * cCharYDim,
			ucLineBuf + iHorizontalScrollPos, iOffsetLength + iByteSpace - iHorizontalScrollPos );
	}

	int iHexStart = iOffsetLength + iByteSpace;
	int iHexXStart = iHexStart * cCharXDim;

	if( iHorizontalScrollPos < iOffsetLength + iByteSpace + iBytesPerLine * iHexWidth )
	{
		TextOut( hdc,
			BORDER_CLIENT_XDIM + ( iHexStart + iBytesPerLine * iHexWidth - iHorizontalScrollPos ) * cCharXDim,
			cClientYPos + BORDER_CLIENT_XDIM + ( iLine - iCurrentLine ) * cCharYDim,
			ucLineBuf + iHexStart + iBytesPerLine * iHexWidth,
			iCharSpace );
	}

	iSelBkColor = PALETTERGB (GetRValue(iSelBkColorValue),GetGValue(iSelBkColorValue),GetBValue(iSelBkColorValue));
	iSelTextColor = PALETTERGB (GetRValue(iSelTextColorValue),GetGValue(iSelTextColorValue),GetBValue(iSelTextColorValue));
	BOOL bLastTextNorm = TRUE;
	COLORREF crefOldColor = GetTextColor(hdc);
	int p = 0, el = iStartPos + iBytesPerLine - 1 - 1, s, e;
	for( p = iStartPos; p <= el; p++ )
	{
		s = iOffsetLength + iByteSpace + ( p - iStartPos + 1 ) * iHexWidth;
		e = s - iHexWidth;
		if( iHorizontalScrollPos < s && iHorizontalScrollPos + cxBuffer >= e && !bHideHex)
		{
			if( bSelected && IN_BOUNDS( p, iStartOfSelection, iEndOfSelection) )
			{
				if( bLastTextNorm )
				{
					//crefOldColor = iSelTextColor;
					SetTextColor (hdc, iSelTextColor);
					SetBkColor (hdc, iSelBkColor);
					bLastTextNorm = FALSE;
				}
				else
				{
					SetTextColor (hdc, iSelTextColor);
					SetBkColor (hdc, iSelBkColor);
				}
			}
			else
			{
				if(bLastTextNorm)
				{
					
					if(p % 2 == 0)
						SetTextColor(hdc,iTextColorE);
					else if(p % 2 != 0)
						SetTextColor(hdc,iTextColorO);
				}
				else
				{
					if(p % 2 == 0)
						SetTextColor(hdc,iTextColorE);
					else if(p % 2 != 0)
						SetTextColor(hdc,iTextColorO);
					SetBkColor (hdc, iBkColor);
				}
			}
			if(p < (int)vChanges.size())
			{
				if(vChanges[p] == COLORCHANGE)
					SetTextColor(hdc,iChangesColorValue);
				//else if(vChanges[p] == COLORHIGHLIGHT)
				//	SetTextColor(hdc,iHighlightColorValue);
				else if(vHighlights[p] == COLORHIGHLIGHT)
					SetTextColor(hdc,iHighlightColorValue);
			}
			if( bSelected && p == iEndOfSelection)
			{
				TextOut( hdc,
				BORDER_CLIENT_XDIM + ( iHexStart + ( p - iStartPos ) * iHexWidth - iHorizontalScrollPos ) * cCharXDim,
				cClientYPos + BORDER_CLIENT_XDIM + ( iLine - iCurrentLine ) * cCharYDim,
				ucLineBuf + iHexStart + ( p - iStartPos ) * iHexWidth,
				iHexWidth - 1 );
			}
			else
			{
				TextOut( hdc,
				BORDER_CLIENT_XDIM + ( iHexStart + ( p - iStartPos ) * iHexWidth - iHorizontalScrollPos ) * cCharXDim,
				cClientYPos + BORDER_CLIENT_XDIM + ( iLine - iCurrentLine ) * cCharYDim,
				ucLineBuf + iHexStart + ( p - iStartPos ) * iHexWidth,
				iHexWidth );
			}
			
			SetTextColor(hdc,crefOldColor);
		}
		if(!bHideHex)
		{
			s = iOffsetLength + iByteSpace + iBytesPerLine * iHexWidth + iCharSpace + ( p - iStartPos + 1);
		}
		else
		{
			s = iOffsetLength + iByteSpace /*+ iBytesPerLine * iHexWidth + iCharSpace*/ + ( p - iStartPos + 1);
		}
		if( iHorizontalScrollPos < s && iHorizontalScrollPos + cxBuffer >= s - 1 )
		{
			if( bSelected && IN_BOUNDS( p, iStartOfSelection, iEndOfSelection) )
			{
				if( bLastTextNorm )
				{
					SetTextColor (hdc, iSelTextColor);
					SetBkColor (hdc, iSelBkColor);
					bLastTextNorm = FALSE;
				}
				else
				{
					SetTextColor (hdc, iSelTextColor);
					SetBkColor (hdc, iSelBkColor);
				}
			}
			else
			{
				if( !bLastTextNorm )
				{
					SetTextColor (hdc, iTextColor);
					SetBkColor (hdc, iBkColor);
					bLastTextNorm = TRUE;
				}
				else
				{
					SetTextColor (hdc, iTextColor);
					SetBkColor (hdc, iBkColor);
				}
			}
			if(p < (int)vChanges.size())
			{
				if(vChanges[p] == COLORCHANGE)
					SetTextColor(hdc,iChangesColorValue);
				//else if(vChanges[p] == COLORHIGHLIGHT)
				else if(vHighlights[p] == COLORHIGHLIGHT)
					SetTextColor(hdc,iHighlightColorValue);
				//else if(vChanges[p] == COLORDTE)
				else if(vDTEs[p] == COLORDTE)
					SetTextColor(hdc,iDTEColorValue);
			}

			// render using ascii encoding
			if(!bThingyView)
			{
				if(!bHideHex)
				{
					TextOut( hdc,
					BORDER_CLIENT_XDIM + ( iHexStart + iBytesPerLine * iHexWidth + iCharSpace + ( p - iStartPos ) - iHorizontalScrollPos ) * cCharXDim,
					cClientYPos + BORDER_CLIENT_XDIM + ( iLine - iCurrentLine ) * cCharYDim,
					ucLineBuf + iHexStart + iBytesPerLine * iHexWidth + iCharSpace + ( p - iStartPos ),
					1 );
				}
				else
				{
					TextOut( hdc,
					BORDER_CLIENT_XDIM + ( iHexStart /*+ iBytesPerLine * iHexWidth + iCharSpace*/ + ( p - iStartPos ) - iHorizontalScrollPos ) * cCharXDim,
					cClientYPos + BORDER_CLIENT_XDIM + ( iLine - iCurrentLine ) * cCharYDim,
					ucLineBuf + iHexStart + iBytesPerLine * iHexWidth + iCharSpace + ( p - iStartPos ),
					1 );
				}
			}
			// otherwise use a table
			else
			{
				if(bJapanese)
				{
					//GetObject(hdc,GetObject( hdc,0,NULL),hfOld); 
					SelectObject( hdc, hfJap);
				}
				if(p-iStartPos < (int)vAsciiLengths.size())
				{
					LPCTSTR l=output.c_str();

					if(!bHideHex)
					{
						TextOut( hdc,
						BORDER_CLIENT_XDIM + ( totallength + iHexStart + iBytesPerLine * iHexWidth + iCharSpace  - iHorizontalScrollPos ) * cCharXDim,
						cClientYPos + BORDER_CLIENT_XDIM + ( iLine - iCurrentLine ) * cCharYDim,
						&l[totallength] /*(output.substr(totallength,vAsciiLengths[p-iStartPos])).c_str()*/,
						vAsciiLengths[p - iStartPos]);
						totallength += vAsciiLengths[p-iStartPos];
					}
					else
					{
						TextOut( hdc,
						BORDER_CLIENT_XDIM + ( totallength + iHexStart /*+ iBytesPerLine * iHexWidth + iCharSpace*/  - iHorizontalScrollPos ) * cCharXDim,
						cClientYPos + BORDER_CLIENT_XDIM + ( iLine - iCurrentLine ) * cCharYDim,
						&l[totallength] /*(output.substr(totallength,vAsciiLengths[p-iStartPos])).c_str()*/,
						vAsciiLengths[p - iStartPos]);
						totallength += vAsciiLengths[p-iStartPos];
					}
				}
				if(p + 1 > el)
				{
					if(!bHideHex)
					{
						TextOut( hdc,
						BORDER_CLIENT_XDIM + ( totallength + iHexStart + iBytesPerLine * iHexWidth + iCharSpace  - iHorizontalScrollPos ) * cCharXDim,
						cClientYPos + BORDER_CLIENT_XDIM + ( iLine - iCurrentLine ) * cCharYDim,
						(output.substr(totallength,output.length()-totallength)).c_str(),
						output.length()-totallength);
					}
					else
					{
						TextOut( hdc,
						BORDER_CLIENT_XDIM + ( totallength + iHexStart /*+ iBytesPerLine * iHexWidth + iCharSpace*/  - iHorizontalScrollPos ) * cCharXDim,
						cClientYPos + BORDER_CLIENT_XDIM + ( iLine - iCurrentLine ) * cCharYDim,
						(output.substr(totallength,output.length()-totallength)).c_str(),
						output.length()-totallength);
					}
				}
				if(bJapanese)
				{
					//DeleteObject( hdc);
					//SelectObject( hdc, hfOld);			
					make_font();
					SelectObject(hdc, hFont);
				}
			}
		}
	}
	s = iOffsetLength + iByteSpace + ( p - iStartPos + 1 ) * iHexWidth;
	e = s - iHexWidth;
	if( iHorizontalScrollPos < s && iHorizontalScrollPos + cxBuffer >= e && !bHideHex)
	{
		if( bSelected && IN_BOUNDS( p, iStartOfSelection, iEndOfSelection ) )
		{
			if( bLastTextNorm )
			{
				TextOut( hdc,
					BORDER_CLIENT_XDIM + ( iHexStart + ( p - iStartPos ) * iHexWidth - iHorizontalScrollPos ) * cCharXDim + 2 * cCharXDim,
					cClientYPos + BORDER_CLIENT_XDIM + ( iLine - iCurrentLine ) * cCharYDim,
					_T(" "),
					1 );
				crefOldColor = iSelTextColor;
				SetTextColor (hdc, iSelTextColor);
				SetBkColor (hdc, iSelBkColor);
				if(p < (int)vChanges.size())
				{
					if(vChanges[p] == COLORCHANGE)
						SetTextColor(hdc,iChangesColorValue);
					//else if(vChanges[p] == COLORHIGHLIGHT)
					else if(vHighlights[p] == COLORHIGHLIGHT)
						SetTextColor(hdc,iHighlightColorValue);
				}
				bLastTextNorm = FALSE;
				bLastTextNorm = TRUE;
				TextOut( hdc,
					BORDER_CLIENT_XDIM + ( iHexStart + ( p - iStartPos ) * iHexWidth - iHorizontalScrollPos ) * cCharXDim,
					cClientYPos + BORDER_CLIENT_XDIM + ( iLine - iCurrentLine ) * cCharYDim,
					ucLineBuf + iHexStart + ( p - iStartPos ) * iHexWidth,
					iHexWidth - 1 );
			}
			else
			{
				crefOldColor = iSelTextColor;
				SetTextColor (hdc, iSelTextColor);
				SetBkColor (hdc, iSelBkColor);
				if(p < (int)vChanges.size())
				{
					if(vChanges[p] == COLORCHANGE)
						SetTextColor(hdc,iChangesColorValue);
					//else if(vChanges[p] == COLORHIGHLIGHT)
					else if(vHighlights[p] == COLORHIGHLIGHT)
						SetTextColor(hdc,iHighlightColorValue);
				}
				TextOut( hdc,
					BORDER_CLIENT_XDIM + ( iHexStart + ( p - iStartPos ) * iHexWidth - iHorizontalScrollPos ) * cCharXDim,
					cClientYPos + BORDER_CLIENT_XDIM + ( iLine - iCurrentLine ) * cCharYDim,
					ucLineBuf + iHexStart + ( p - iStartPos ) * iHexWidth,
					iHexWidth - 1 );

				SetTextColor (hdc, iTextColor);
				crefOldColor = iTextColor;
				SetBkColor (hdc, iBkColor);
				bLastTextNorm = TRUE;
				TextOut( hdc,
					BORDER_CLIENT_XDIM + ( iHexStart + ( p - iStartPos ) * iHexWidth - iHorizontalScrollPos ) * cCharXDim + 2 * cCharXDim,
					cClientYPos + BORDER_CLIENT_XDIM + ( iLine - iCurrentLine ) * cCharYDim,
					_T(" "),
					1 );
			}
		}
		else
		{
			if( !bLastTextNorm )
			{
				if(p < (int)vChanges.size() && vChanges[p] == COLORCHANGE)
					SetTextColor(hdc,iChangesColorValue);
				else if(p < (int)vChanges.size() && vHighlights[p] == COLORHIGHLIGHT)
					SetTextColor(hdc,iHighlightColorValue);
				else if(p % 2 == 0)
					SetTextColor(hdc,iTextColorE);
				else if(p % 2 != 0)
					SetTextColor(hdc,iTextColorO);
				crefOldColor = iTextColor;
				SetBkColor (hdc, iBkColor);
				bLastTextNorm = TRUE;
			}
			else
			{
				crefOldColor = GetTextColor(hdc);
				if(p < (int)vChanges.size() && vChanges[p] == COLORCHANGE)
					SetTextColor(hdc,iChangesColorValue);
				else if(p < (int)vChanges.size() && vHighlights[p] == COLORHIGHLIGHT)
					SetTextColor(hdc,iHighlightColorValue);
				else if(p % 2 == 0)
					SetTextColor(hdc,iTextColorE);
				else if(p % 2 != 0)
					SetTextColor(hdc,iTextColorO);	
			}
			TextOut( hdc,
				BORDER_CLIENT_XDIM + ( iHexStart + ( p - iStartPos ) * iHexWidth - iHorizontalScrollPos ) * cCharXDim,
				cClientYPos + BORDER_CLIENT_XDIM + ( iLine - iCurrentLine ) * cCharYDim,
				ucLineBuf + iHexStart + ( p - iStartPos ) * iHexWidth,
				iHexWidth );
			SetTextColor(hdc,crefOldColor);
		}
	}

	if(!bHideHex)//problem here I think
	{
		s = iOffsetLength + iByteSpace + iBytesPerLine * iHexWidth + iCharSpace + ( p - iStartPos + 1);
	}
	else
	{
		s = iOffsetLength + iByteSpace /*+ iBytesPerLine * iHexWidth* + iCharSpace*/ + ( p - iStartPos + 1);
	}
	if( iHorizontalScrollPos < s && iHorizontalScrollPos + cxBuffer >= s - 1 )
	{
		if( bSelected && IN_BOUNDS( p, iStartOfSelection, iEndOfSelection ) )
		{
			if( bLastTextNorm )
			{
				SetTextColor (hdc, iSelTextColor);
				SetBkColor (hdc, iSelBkColor);
			}
			else
			{
				SetTextColor (hdc, iSelTextColor);
				SetBkColor (hdc, iSelBkColor);
			}
		}
		else
		{
			if( !bLastTextNorm )
			{
				SetTextColor (hdc, iTextColor);
				SetBkColor (hdc, iBkColor);
			}
			else
			{
				SetTextColor (hdc, iTextColor);
				SetBkColor (hdc, iBkColor);
			}
		}
		if(p < (int)vChanges.size())
		{
			if(vChanges[p] == COLORCHANGE)
				SetTextColor(hdc,iChangesColorValue);
			//else if(vChanges[p] == COLORHIGHLIGHT)
			else if(vHighlights[p] == COLORHIGHLIGHT)
				SetTextColor(hdc,iHighlightColorValue);
			//else if(vChanges[p] == COLORDTE)
			else if(vDTEs[p] == COLORDTE)
				SetTextColor(hdc,iDTEColorValue);
		}
		if(!bThingyView)
		{
			if(!bHideHex)
			{
				TextOut( hdc,
					BORDER_CLIENT_XDIM + ( iHexStart + iBytesPerLine * iHexWidth + iCharSpace + ( p - iStartPos ) - iHorizontalScrollPos ) * cCharXDim,
					cClientYPos + BORDER_CLIENT_XDIM + ( iLine - iCurrentLine ) * cCharYDim,
					ucLineBuf + iHexStart + iBytesPerLine * iHexWidth + iCharSpace + ( p - iStartPos ),
					1 );
			}
			else
			{
				TextOut( hdc,
					BORDER_CLIENT_XDIM + ( iHexStart /*+ iBytesPerLine * iHexWidth + iCharSpace*/ + ( p - iStartPos ) - iHorizontalScrollPos ) * cCharXDim,
					cClientYPos + BORDER_CLIENT_XDIM + ( iLine - iCurrentLine ) * cCharYDim,
					ucLineBuf + iHexStart + iBytesPerLine * iHexWidth + iCharSpace + ( p - iStartPos ),
					1 );
			}
		}
		else
		{
			if(bJapanese)
			{
				//GetObject(hdc,GetObject( hdc,0,NULL),hfOld); 
				SelectObject( hdc, hfJap);
			}
			if(p-iStartPos < (int)vAsciiLengths.size())
			{
				if(!bHideHex)
				{
					TextOut( hdc,
					BORDER_CLIENT_XDIM + ( totallength + iHexStart + iBytesPerLine * iHexWidth + iCharSpace  - iHorizontalScrollPos ) * cCharXDim,
					cClientYPos + BORDER_CLIENT_XDIM + ( iLine - iCurrentLine ) * cCharYDim,
					(output.substr(totallength,vAsciiLengths[p-iStartPos])).c_str(),
					vAsciiLengths[p - iStartPos]);
					totallength += vAsciiLengths[p-iStartPos];
				}
				else
				{
					TextOut( hdc,
					BORDER_CLIENT_XDIM + ( totallength + iHexStart /*+ iBytesPerLine * iHexWidth + iCharSpace*/  - iHorizontalScrollPos ) * cCharXDim,
					cClientYPos + BORDER_CLIENT_XDIM + ( iLine - iCurrentLine ) * cCharYDim,
					(output.substr(totallength,vAsciiLengths[p-iStartPos])).c_str(),
					vAsciiLengths[p - iStartPos]);
					totallength += vAsciiLengths[p-iStartPos];
				}
			}
			if(p + 1 > el)
			{
				if(!bHideHex)
				{
					TextOut( hdc,
					BORDER_CLIENT_XDIM + ( totallength + iHexStart + iBytesPerLine * iHexWidth + iCharSpace  - iHorizontalScrollPos ) * cCharXDim,
					cClientYPos + BORDER_CLIENT_XDIM + ( iLine - iCurrentLine ) * cCharYDim,
					(output.substr(totallength,output.length()-totallength)).c_str(),
					output.length()-totallength);
				}
				else
				{
					TextOut( hdc,
					BORDER_CLIENT_XDIM + ( totallength + iHexStart /*+ iBytesPerLine * iHexWidth + iCharSpace*/  - iHorizontalScrollPos ) * cCharXDim,
					cClientYPos + BORDER_CLIENT_XDIM + ( iLine - iCurrentLine ) * cCharYDim,
					(output.substr(totallength,output.length()-totallength)).c_str(),
					output.length()-totallength);
				}
			}
			if(bJapanese)
			{
				//SelectObject( hdc, hfOld);	
				make_font();
				SelectObject(hdc,hFont);
				//DeleteObject( hdc );
			}
			
		}
	}

	if(bHideHex)
	{
		m = (iOffsetLength+iByteSpace)*cCharXDim - cCharXDim/2 + 3*cCharXDim*4*0 - cCharXDim*iHorizontalScrollPos;
		MoveToEx (hdc,
			BORDER_CLIENT_XDIM+m,
			cClientYPos + BORDER_CLIENT_XDIM+(iLine-iCurrentLine)*cCharYDim, NULL);
		LineTo (hdc,
			BORDER_CLIENT_XDIM+m,
			cClientYPos + BORDER_CLIENT_XDIM+(iLine-iCurrentLine+1)*cCharYDim);
	}
	else
	{
		for (i = 0; i < (iBytesPerLine / 4) + 1; i++)
		{
			m = (iOffsetLength+iByteSpace)*cCharXDim - cCharXDim/2 + 3*cCharXDim*4*i - cCharXDim*iHorizontalScrollPos;
			MoveToEx (hdc,
				BORDER_CLIENT_XDIM+m,
				cClientYPos + BORDER_CLIENT_XDIM+(iLine-iCurrentLine)*cCharYDim, NULL);
			LineTo (hdc,
				BORDER_CLIENT_XDIM+m,
				cClientYPos + BORDER_CLIENT_XDIM+(iLine-iCurrentLine+1)*cCharYDim);
		}
	}

	if(!bHideHex)
	{
		m = (iOffsetLength + iByteSpace + iBytesPerLine * 3 + iCharSpace)*cCharXDim - cCharXDim*iHorizontalScrollPos - 2;
		MoveToEx (hdc,
			BORDER_CLIENT_XDIM+m,
			cClientYPos + BORDER_CLIENT_XDIM+(iLine-iCurrentLine)*cCharYDim, NULL);
		LineTo (hdc,
			BORDER_CLIENT_XDIM+m,
			cClientYPos + BORDER_CLIENT_XDIM+(iLine-iCurrentLine+1)*cCharYDim);
		MoveToEx (hdc,
			BORDER_CLIENT_XDIM+m+2,
			cClientYPos + BORDER_CLIENT_XDIM+(iLine-iCurrentLine)*cCharYDim, NULL);
		LineTo (hdc,
			BORDER_CLIENT_XDIM+m+2,
			cClientYPos + BORDER_CLIENT_XDIM+(iLine-iCurrentLine+1)*cCharYDim);
	}
	el = iStartPos + iBytesPerLine - 1;
	int iCharCoordinate;
	RECT r;
	long bookmark = 0;
	for( i = 0; i < iBookmarkCount && !bHideHex; i++ )
	{
		bookmark = pbmkList[i].offset;
		if(iOffsetMode == LOROM)
			bookmark = fromLOROM(bookmark);
		else if(iOffsetMode == HIROM)
			bookmark = fromHIROM(bookmark);
		if( IN_BOUNDS( bookmark, iStartPos, el ) && bookmark <= FileBuffer.Upper() )
		{
			iCharCoordinate = iOffsetLength + iByteSpace + ( bookmark % iBytesPerLine )*3 - iHorizontalScrollPos;
			r.left = BORDER_CLIENT_XDIM + iCharCoordinate * cCharXDim;
			r.top = cClientYPos + BORDER_CLIENT_XDIM + ( bookmark / iBytesPerLine - iCurrentLine ) * cCharYDim;
			r.right = BORDER_CLIENT_XDIM + r.left + 2*cCharXDim;
			r.bottom = cClientYPos + BORDER_CLIENT_XDIM + ( bookmark / iBytesPerLine - iCurrentLine + 1 ) * cCharYDim;
			FrameRect( hdc, &r, hbr );

			iCharCoordinate = iOffsetLength + iByteSpace + iBytesPerLine*3 + iCharSpace
				+ ( bookmark % iBytesPerLine ) - iHorizontalScrollPos;
			r.left = BORDER_CLIENT_XDIM + iCharCoordinate * cCharXDim;
			r.top = cClientYPos + BORDER_CLIENT_XDIM + ( bookmark / iBytesPerLine - iCurrentLine) * cCharYDim;
			r.right = BORDER_CLIENT_XDIM + ( iCharCoordinate + 1 ) * cCharXDim;
			r.bottom = cClientYPos + BORDER_CLIENT_XDIM + ( bookmark / iBytesPerLine - iCurrentLine + 1 ) * cCharYDim;
			if(!bThingyView)
			{
				FrameRect( hdc, &r, hbr );
			}
		}
	}
	if(bHideHex)
	{
		int j = 0;
		_tstring blank;
		for(j = 0;j < iBytesPerLine*4;j++)
			blank += L" ";
		TextOut( hdc,
			BORDER_CLIENT_XDIM + ( totallength + iHexStart + iBytesPerLine /** iHexWidth + iCharSpace*/  - iHorizontalScrollPos ) * cCharXDim,
			cClientYPos + BORDER_CLIENT_XDIM + ( iLine - iCurrentLine ) * cCharYDim,
		blank.c_str(),
		blank.length());
	}
	return;
}

void Translhextion::adjust_view_for_cursor ()
{
	int iColumn_logical;
	if (iTextEntryMode == BYTES)
		iColumn_logical = (iOffsetLength + iByteSpace + (iCurrentByte % iBytesPerLine) * 3 + iCurrentNibble);
	else
		iColumn_logical = ((iOffsetLength + iByteSpace + iBytesPerLine * 3 + iCharSpace) + (iCurrentByte % iBytesPerLine));

	if (iColumn_logical >= iHorizontalScrollPos+cxBuffer)
		iHorizontalScrollPos = iColumn_logical-(cxBuffer-1);
	else if (iColumn_logical < iHorizontalScrollPos)
		iHorizontalScrollPos = iColumn_logical;
	update_horizontal_scrollbar ();
}

int Translhextion::lbuttonup (int xPos, int yPos)
{
	KillTimer (*this, iTimerID);
	bTimerSet = FALSE;
	SetCursor( LoadCursor( NULL, IDC_ARROW ) );
	ReleaseCapture ();
	bLButtonIsDown = FALSE;
	if (iLBDownX == xPos && iLBDownY == yPos)
	{
		int iColumnOnScreen = xPos / cCharXDim, 
			iRowOnScreen = yPos / cCharYDim,	
			iColumn_logical = iColumnOnScreen + iHorizontalScrollPos,	
			iLine = iCurrentLine + iRowOnScreen; 

		if (iColumn_logical >= iOffsetLength + iByteSpace && iColumn_logical <= iCharsPerLine - 1 - iBytesPerLine - iCharSpace - 1)
		{
			if ((iColumn_logical-iOffsetLength-(iByteSpace-1))%3 != 0)
			{
				int bytenum = (iColumn_logical-iOffsetLength-(iByteSpace-1))/3,
					iNumOfNib = ((iColumn_logical-iOffsetLength-(iByteSpace-1))%3)-1;
				int newpos = iLine * iBytesPerLine + bytenum;
				if( newpos <= (FileBuffer.Upper ()) + 1 )
				{
					iCurrentByte = newpos;
					iCurrentNibble = iNumOfNib;
					iTextEntryMode = BYTES;
					repaint ();
				}
			}
		}
		else if (!bThingyView && iColumn_logical > iCharsPerLine - 1 - iBytesPerLine	&& iColumn_logical < iCharsPerLine)
		{
			int newpos = iLine * iBytesPerLine + (iColumn_logical - (iCharsPerLine - iBytesPerLine));
			if( newpos <= (FileBuffer.Upper ()) + 1 )
			{
				iCurrentByte = newpos;
				iTextEntryMode = CHARS;
				repaint ();
			}
		}
	}
	return 0;
}

int Translhextion::rbuttonup (int xPos, int yPos)
{
	KillTimer (*this, iTimerID);
	bTimerSet = FALSE;
	SetCursor( LoadCursor( NULL, IDC_ARROW ) );
	ReleaseCapture ();
	int iColumnOnScreen = xPos / cCharXDim, 
		iRowOnScreen = yPos / cCharYDim,	
		iColumn_logical = iColumnOnScreen + iHorizontalScrollPos,	
		iLine = iCurrentLine + iRowOnScreen; 
	//HMENU context = LoadMenu(hInstance,MAKEINTRESOURCE(IDR_RIGHTCLICKMENU));
	HMENU context = CreatePopupMenu();
	AppendMenu (context, MF_ENABLED | MF_STRING, 1, _T("Cu&t"));
	if(bThingyView)
	{
		AppendMenu (context, MF_ENABLED | MF_STRING, 2, _T("Thingy &Copy"));
	}
	else
	{
		AppendMenu (context, MF_ENABLED | MF_STRING, 2, _T("&Copy"));
	}
	AppendMenu (context, MF_ENABLED | MF_STRING, 3, _T("&Paste"));
	AppendMenu (context, MF_ENABLED | MF_STRING, 4, _T("P&aste preview"));
	if((bTableLoaded && bTableActive && FileBuffer.Length() > 0 ) ||
		(bTableLoaded && bTableActive && !bReadOnly) || ( FileBuffer.Length() > 0 ))
		AppendMenu (context, MF_ENABLED | MF_SEPARATOR, 0, _T("appended"));
	AppendMenu (context, MF_ENABLED | MF_STRING, 5, _T("&Dump Script..."));
	AppendMenu (context, MF_ENABLED | MF_STRING, 6, _T("&Replace Script..."));
	AppendMenu (context, MF_ENABLED | MF_STRING, 7, _T("H&exdump..."));
	if(( FileBuffer.Length() > 0 ))
		AppendMenu (context, MF_ENABLED | MF_SEPARATOR, 0, _T("appended"));
	AppendMenu (context, MF_ENABLED | MF_STRING, 8, _T("&Jump To..."));
	if(( FileBuffer.Length() > 0 ))
		AppendMenu (context, MF_ENABLED | MF_SEPARATOR, 0, _T("appended"));
	AppendMenu (context, MF_ENABLED | MF_STRING, 9, _T("Select &all"));
	if( ( bSelected || iCurrentByte <= FileBuffer.Upper() ) && !bReadOnly && !bPartialOpen )
		;
	else
		RemoveMenu(context,1,MF_BYCOMMAND); //CUT
	if( bSelected || iCurrentByte <= FileBuffer.Upper() )
		;
	else
		RemoveMenu(context,2,MF_BYCOMMAND); //COPY
	if( !bReadOnly && !bSelected )
	{
		if( OpenClipboard( NULL ) )
		{
			HGLOBAL hClipMemory = GetClipboardData( CF_TEXT );
			if( hClipMemory != NULL )
				;
			else
				RemoveMenu(context,3,MF_BYCOMMAND); //PASTE
			CloseClipboard ();
		}
		else
		{
			// Clipboard could not be opened => can't paste.
			RemoveMenu(context,3,MF_BYCOMMAND); //PASTE
		}
	}
	else
		RemoveMenu(context,3,MF_BYCOMMAND); //PASTE
	if( !bReadOnly && !bSelected )
		;
	else
		RemoveMenu(context,4,MF_BYCOMMAND); //PASTE PREVIEW
	if(bTableLoaded && bTableActive && FileBuffer.Length() > 0 )
		;
	else
		RemoveMenu(context,5,MF_BYCOMMAND);//DUMP SCRIPT
	if(bTableLoaded && bTableActive && !bReadOnly)
		;
	else
		RemoveMenu(context,6,MF_BYCOMMAND);//REPLACE SCRIPT
	if( FileBuffer.Length() > 0 )
		;
	else
		RemoveMenu(context,7,MF_BYCOMMAND); //HEXDUMP
	if( FileBuffer.Length() > 0 )
		;
	else
		RemoveMenu(context,8,MF_BYCOMMAND); //JUMP TO
	if( FileBuffer.Length() > 0 )
		;
	else
		RemoveMenu(context,9,MF_BYCOMMAND); //SELECT ALL
	
	POINT pt;
	pt.x = xPos;
	pt.y = yPos;
	ClientToScreen(*this, &pt); 
	//iWindowWidth = wndpl.rcNormalPosition.right - iWindowX;
	//iWindowHeight = wndpl.rcNormalPosition.bottom - iWindowY;
	UINT Msg = TrackPopupMenu(context,TPM_RETURNCMD | TPM_LEFTBUTTON | TPM_TOPALIGN | TPM_LEFTALIGN,pt.x,pt.y,0,*this,0);

	//UINT Msg = TrackPopupMenu(context,TPM_RETURNCMD | TPM_LEFTBUTTON | TPM_TOPALIGN | TPM_LEFTALIGN,xPos + iWindowX,yPos + iWindowY + 40,0,hwnd,0);
	switch(Msg)
	{
	case 0:
		break;
	case 1:
		OnCommand(IDM_EDIT_CUT,0);
		break;
	case 2:
		OnCommand(IDM_EDIT_COPY,0);
		break;
	case 3:
		OnCommand(IDM_EDIT_PASTE,0);
		break;
	case 4:
		OnCommand(IDM_PASTE_WITH_DLG,0);
		break;
	case 5:
		OnCommand(IDM_SCRIPT_DUMP,0);
		break;
	case 6:
		OnCommand(IDM_REPLACE_SCRIPT,0);
		break;
	case 7:
		OnCommand(IDM_COPY_HEXDUMP,0);
		break;
	case 8:
		OnCommand(IDM_GO_TO,0);
		break;
	case 9:
		OnCommand(IDM_SELECT_ALL,0);
		break;
	default:
		break;
	}
	return true;
}

int Translhextion::mousemove (int xPos, int yPos)
{
	iMouseX = xPos;
	iMouseY = yPos;
	if (bLButtonIsDown == FALSE)
		return 0;
	bSelected = TRUE;
	if (GetCapture() == NULL)
	{
		SetCapture (*this);
		SetCursor( LoadCursor( NULL, IDC_IBEAM ) );
	}

	int iColumnOnScreen = xPos / cCharXDim,
		iRowOnScreen = yPos / cCharYDim,
		iColumn_logical = iColumnOnScreen + iHorizontalScrollPos,
		iLine = iCurrentLine + iRowOnScreen;

	if (yPos>cBufferY*cCharYDim || yPos<0)
	{
		if (bTimerSet==FALSE)
		{
			SetTimer (*this, iTimerID, iTimerLength, NULL);
			bTimerSet = TRUE;
		}
	}
	else if (iColumn_logical >= iOffsetLength + iByteSpace && iColumn_logical <= iCharsPerLine - 1 - iBytesPerLine - iCharSpace - 1)
	{
		KillTimer (*this, iTimerID);
		bTimerSet = FALSE;
		if ((iColumn_logical-iOffsetLength-(iByteSpace-1))%3 != 0)
		{
			int bytenum = (iColumn_logical-iOffsetLength-(iByteSpace-1))/3,
				iNumOfNib = ((iColumn_logical-iOffsetLength-(iByteSpace-1))%3)-1;
			int newpos = iLine * iBytesPerLine + bytenum;
			if (newpos <= (FileBuffer.Upper ()))
			{
				iEndOfSelection = newpos;
				repaint ();
			}
		}
	}
	else if (iColumn_logical > iCharsPerLine - 1 - iBytesPerLine	&& iColumn_logical < iCharsPerLine)
	{
		KillTimer (*this, iTimerID);
		bTimerSet = FALSE;
		int newpos = iLine * iBytesPerLine + (iColumn_logical - (iCharsPerLine - iBytesPerLine));
		if (newpos <= (FileBuffer.Upper ()))
		{
			iEndOfSelection = newpos;
			repaint ();
		}
	}
	return 0;
}

int Translhextion::lbuttondown (int xPos, int yPos)
{
	if ((filename[0] == '\0'))
		return 0;

	//yPos+=cClientYPos;
	if(bHideHex)
	{
		return 0;
	}
	int iColumnOnScreen = xPos / cCharXDim,
		iRowOnScreen = yPos / cCharYDim,
		iColumn_logical = iColumnOnScreen + iHorizontalScrollPos,
		iLine = iCurrentLine + iRowOnScreen;
	iLBDownX = xPos;
	iLBDownY = yPos;

	if (iColumn_logical >= iOffsetLength + iByteSpace && iColumn_logical <= iCharsPerLine - 1 - iBytesPerLine - iCharSpace - 1)
	{
		if ((iColumn_logical-iOffsetLength-(iByteSpace-1))%3 != 0)
		{
			bLButtonIsDown = TRUE;
			bSelected = FALSE;
			int bytenum = (iColumn_logical-iOffsetLength-(iByteSpace-1))/3,
				iNumOfNib = ((iColumn_logical-iOffsetLength-(iByteSpace-1))%3)-1;
			int newpos = iLine * iBytesPerLine + bytenum;
			if( newpos <= (FileBuffer.Upper ()) )
			{
				iStartOfSelection = newpos;
				iEndOfSelection = newpos;
			}
			else if( newpos == (FileBuffer.Upper ()) + 1 )
			{
				bLButtonIsDown = FALSE; 
			}
		}
	}
	
	else if (!bThingyView && iColumn_logical > iCharsPerLine - 1 - iBytesPerLine	&& iColumn_logical < iCharsPerLine)
	{
		bLButtonIsDown = TRUE;
		bSelected = FALSE;
		int newpos = iLine * iBytesPerLine + (iColumn_logical - (iCharsPerLine - iBytesPerLine));
		if( newpos <= (FileBuffer.Upper ()) )
		{
			iStartOfSelection = newpos;
			iEndOfSelection = newpos;
		}
		else if( newpos == (FileBuffer.Upper ()) + 1 )
		{
			bLButtonIsDown = FALSE; 
		}
	}
	return 0;
}



void Translhextion::update_size_change ()
{
	RECT r;
	GetClientRect (*this, &r);

	resize_window (r.right, r.bottom);
}


int Translhextion::select_with_arrowkeys (int key)
{
	if (filename[0] == '\0' || iCurrentByte>(FileBuffer.Upper ()) || iCurrentByte<0)
		return 0;
	switch (key)
	{
	case IDA_SELECTSTARTOFLINE:
		if (!bSelected)
		{
			bSelected = TRUE;
			iStartOfSelection = iCurrentByte;
			iEndOfSelection = iCurrentByte;
		}
		iEndOfSelection=iEndOfSelection/iBytesPerLine*iBytesPerLine;
		break;

	case IDA_SELECTENDOFLINE:
		if (!bSelected)
		{
			bSelected = TRUE;
			iStartOfSelection = iCurrentByte;
			iEndOfSelection = iCurrentByte;
		}
		iEndOfSelection=(iEndOfSelection/iBytesPerLine+1)*iBytesPerLine-1;
		if (iEndOfSelection>(FileBuffer.Upper ()))
			iEndOfSelection = (FileBuffer.Upper ());
		break;

	case IDA_SELECTSTARTOFFILE:
		if (!bSelected)
		{
			bSelected = TRUE;
			iStartOfSelection = iCurrentByte;
		}
		iEndOfSelection=0;
		break;

	case IDA_SELECTENDOFFILE:
		if (!bSelected)
		{
			bSelected = TRUE;
			iStartOfSelection = iCurrentByte;
		}
		iEndOfSelection = (FileBuffer.Upper ());
		break;

	case IDA_SELECTPAGEDOWN:
		if (!bSelected)
		{
			bSelected = TRUE;
			iStartOfSelection = iCurrentByte;
			iEndOfSelection = iCurrentByte;
		}
		iEndOfSelection += cBufferY*iBytesPerLine;
		if (iEndOfSelection>(FileBuffer.Upper ()))
			iEndOfSelection=(FileBuffer.Upper ());
		break;

	case IDA_SELECTPAGEUP:
		if (!bSelected)
		{
			bSelected = TRUE;
			iStartOfSelection = iCurrentByte;
			iEndOfSelection = iCurrentByte;
		}
		iEndOfSelection -= cBufferY*iBytesPerLine;
		if (iEndOfSelection<0)
			iEndOfSelection=0;
		break;

	default:
		if (!bSelected)
		{
			
			bSelected = TRUE;
			iStartOfSelection = iCurrentByte;
			iEndOfSelection = iCurrentByte;
			adjust_view_for_selection ();
			repaint ();
			return 1;
		}
		switch (key)
		{
		case IDA_SELECTLEFT:
			if (iEndOfSelection > 0)
				iEndOfSelection--;
			break;

		case IDA_SELECTRIGHT:
			if (iEndOfSelection < (FileBuffer.Upper ()))
				iEndOfSelection++;
			break;

		case IDA_SELECTUP:
			if (iEndOfSelection > iBytesPerLine)
				iEndOfSelection -= iBytesPerLine;
			else
				iEndOfSelection=0;
			break;

		case IDA_SELECTDOWN:
			if (iEndOfSelection+iBytesPerLine < (FileBuffer.Upper ()))
				iEndOfSelection += iBytesPerLine;
			else
				iEndOfSelection = (FileBuffer.Upper ());
			break;

		default:
			break;
		}
	}
	iCurrentByte = iEndOfSelection;
	adjust_view_for_selection ();
	repaint ();
	return 1;
}


void Translhextion::adjust_view_for_selection ()
{
	if( bSelected )
	{
		
		if( iEndOfSelection / iBytesPerLine < iCurrentLine )
			
			iCurrentLine = iEndOfSelection / iBytesPerLine;

		
		else if( iEndOfSelection/iBytesPerLine > iCurrentLine+cBufferY - 1 )
		{
			
			iCurrentLine = iEndOfSelection / iBytesPerLine - cBufferY + 1;
			if( iCurrentLine < 0 )
				iCurrentLine = 0;
		}
		update_vertical_scrollbar();
	}
}

#include "markupex.h"

int Translhextion::read_ini_data ()
{
	CMarkupEX xml;
	xml_name.Format(_T("%stranslhextion.xml"),sAppPath.c_str());

	if(xml.Open(xml_name) && xml.FindElem(_T("TranslhextionConfiguration")))
	{
		iTextColorValue=(COLORREF)xml.GetValue(_T("iTextColorValue"));
		iTextColorEValue=(COLORREF)xml.GetValue(_T("iTextColorEValue"));
		iTextColorOValue=(COLORREF)xml.GetValue(_T("iTextColorOValue"));
		iBkColorValue=(COLORREF)xml.GetValue(_T("iBkColorValue"));
		iSepColorValue=(COLORREF)xml.GetValue(_T("iSepColorValue"));
		iSelTextColorValue=(COLORREF)xml.GetValue(_T("iSelTextColorValue"));
		iSelBkColorValue=(COLORREF)xml.GetValue(_T("iSelBkColorValue"));
		iBookmarkColor=(COLORREF)xml.GetValue(_T("iBookmarkColor"));
		iChangesColorValue=(COLORREF)xml.GetValue(_T("iChangesColorValue"));
		iDTEColorValue=(COLORREF)xml.GetValue(_T("iDTEColorValue"));
		iHighlightColorValue=(COLORREF)xml.GetValue(_T("iHighlightColorValue"));

		//iResourceKey = RegQueryValueEx( hkeyKEY, _T("bAutomaticBPL"), NULL, NULL, (BYTE*) &bAutomaticBPL, &datasize );
		bAutomaticBPL=xml.GetValue(_T("bAutomaticBPL"))&1;
		//iResourceKey = RegQueryValueEx( hkeyKEY, _T("iBytesPerLine"), NULL, NULL, (BYTE*) &iBytesPerLine, &datasize );
		iBytesPerLine=(int)xml.GetValue(_T("iBytesPerLine"));
		//iResourceKey = RegQueryValueEx( hkeyKEY, _T("iOffsetLength"), NULL, NULL, (BYTE*) &iOffsetLength, &datasize );
		iOffsetLength=(int)xml.GetValue(_T("iOffsetLength"));
		//iResourceKey = RegQueryValueEx( hkeyKEY, _T("iCharacterSet"), NULL, NULL, (BYTE*) &iCharacterSet, &datasize );
		iCharacterSet=(int)xml.GetValue(_T("iCharacterSet"));
		//iResourceKey = RegQueryValueEx( hkeyKEY, _T("iFontSize"), NULL, NULL, (BYTE*) &iFontSize, &datasize );
		iFontSize=(int)xml.GetValue(_T("iFontSize"));
		//iResourceKey = RegQueryValueEx( hkeyKEY, _T("iOffsetMode"), NULL, NULL, (BYTE*) &iOffsetMode, &datasize );
		iOffsetMode=(int)xml.GetValue(_T("iOffsetMode"));

		bOpenReadOnly=(int)xml.GetValue(_T("bOpenReadOnly"));
		bDefByteMark=xml.GetValue(_T("bDefByteMark"))&1;
		bDiscardChangesSave=xml.GetValue(_T("bDiscardChangesSave"))&1;

		cTextColor = iTextColorValue;
		cBkColor = iBkColorValue;
		cTextColorE = iTextColorEValue;
		cTextColorO = iTextColorOValue;
		cSepColor = iSepColorValue;
		cSelBkColor = iSelBkColorValue;
		cSelTextColor = iSelTextColorValue;
		cChangesColor = iChangesColorValue;
		cHighlightColor = iHighlightColorValue;
		cBookmarkColor = iBookmarkColor;
		cDTEColor = iDTEColorValue;

		if(xml.FindChildElem(_T("sByteOpen")))
			sByteOpen=(_tstring)xml.GetChildAttrib(_T("val"));
		if(xml.FindChildElem(_T("sByteClose")))
			sByteClose=(_tstring)xml.GetChildAttrib(_T("val"));

		if(xml.FindChildElem(_T("sTexteditorName")))
			sTexteditorName=(_tstring)xml.GetChildData();

		iWindowShowCmd=(int)xml.GetValue(_T("iWindowShowCmd"));
		iWindowX=(int)xml.GetValue(_T("iWindowX"));
		iWindowY=(int)xml.GetValue(_T("iWindowY"));
		iWindowWidth=(int)xml.GetValue(_T("iWindowWidth"));
		iWindowHeight=(int)xml.GetValue(_T("iWindowHeight"));

		iMostRecentCount=0;
		if(xml.FindChildElem(_T("MostRecentFiles")))
		{
			xml.IntoElem();
			for(int i = 0; i <= iMostRecentMaximum; i++, iMostRecentCount++)
			{
				if(!xml.FindChildElem(_T("FileEntry"))) break;
				strMostRecent[i]=xml.GetChildData();
			}
			xml.OutOfElem();
		}

		iMostRecentTableCount=0;
		if(xml.FindChildElem(_T("MostRecentTables")))
		{
			xml.IntoElem();
			for(int i = 0; i <= iMostRecentTableMaximum; i++, iMostRecentTableCount++)
			{
				if(!xml.FindChildElem(_T("TableEntry"))) break;
				strMostRecentTable[i]=xml.GetChildData();
			}
			xml.OutOfElem();
		}
	}
	else
	{
		GString mes;
		mes.Format(LoadString(IDS_NOTICE_INSTALL_CONFIG), sName);
		MessageBox(mes, LoadString(IDS_TITLE_NOTICE), MB_OK | MB_ICONINFORMATION);
		save_ini_data();
	}
	return 0;
}


int Translhextion::save_ini_data ()
{
	CMarkupEX xml;

	xml.SetSignature();
	xml.AddElem(_T("TranslhextionConfiguration"));
	xml.IntoElem();

	iSelBkColorValue = cSelBkColor;
	iSelTextColorValue = cSelTextColor;
	iBookmarkColor = cBookmarkColor;
	iTextColorValue = cTextColor;
	iBkColorValue = cBkColor;
	iTextColorEValue = cTextColorE;
	iTextColorOValue = cTextColorO;
	iSepColorValue = cSepColor;
	iChangesColorValue = cChangesColor;
	iHighlightColorValue = cHighlightColor;
	iDTEColorValue = cDTEColor;

	xml.AddValue(_T("iTextColorValue"),iTextColorValue,CMarkupEX::VALTYPE_RGB);
	xml.AddValue(_T("iTextColorEValue"),iTextColorEValue,CMarkupEX::VALTYPE_RGB);
	xml.AddValue(_T("iTextColorOValue"),iTextColorOValue,CMarkupEX::VALTYPE_RGB);
	xml.AddValue(_T("iBkColorValue"),iBkColorValue,CMarkupEX::VALTYPE_RGB);
	xml.AddValue(_T("iSepColorValue"),iSepColorValue,CMarkupEX::VALTYPE_RGB);
	xml.AddValue(_T("iSelTextColorValue"),iSelTextColorValue,CMarkupEX::VALTYPE_RGB);
	xml.AddValue(_T("iSelBkColorValue"),iSelBkColorValue,CMarkupEX::VALTYPE_RGB);
	xml.AddValue(_T("iBookmarkColor"),iBookmarkColor,CMarkupEX::VALTYPE_RGB);
	xml.AddValue(_T("iChangesColorValue"),iChangesColorValue,CMarkupEX::VALTYPE_RGB);
	xml.AddValue(_T("iDTEColorValue"),iDTEColorValue,CMarkupEX::VALTYPE_RGB);

	xml.AddValue(_T("iHighlightColorValue"),iHighlightColorValue,CMarkupEX::VALTYPE_RGB);
	xml.AddValue(_T("bAutomaticBPL"),bAutomaticBPL&1,CMarkupEX::VALTYPE_DEC);
	xml.AddValue(_T("iBytesPerLine"),iBytesPerLine,CMarkupEX::VALTYPE_DEC);
	xml.AddValue(_T("iOffsetLength"),iOffsetLength,CMarkupEX::VALTYPE_DEC);
	xml.AddValue(_T("iCharacterSet"),iCharacterSet,CMarkupEX::VALTYPE_DEC);
	xml.AddValue(_T("iFontSize"),iFontSize,CMarkupEX::VALTYPE_DEC);
	xml.AddValue(_T("iOffsetMode"),iOffsetMode,CMarkupEX::VALTYPE_DEC);

	xml.AddValue(_T("bOpenReadOnly"),bOpenReadOnly,CMarkupEX::VALTYPE_DEC);
	xml.AddValue(_T("bDefByteMark"),bDefByteMark&1,CMarkupEX::VALTYPE_DEC);
	xml.AddValue(_T("bDiscardChangesSave"),bDiscardChangesSave&1,CMarkupEX::VALTYPE_DEC);

	xml.AddElem(_T("sByteOpen"));
	xml.SetAttrib(_T("val"),sByteOpen.c_str());
	xml.AddElem(_T("sByteClose"));
	xml.SetAttrib(_T("val"),sByteClose.c_str());

	xml.AddElem(_T("sTexteditorName"),sTexteditorName.c_str());

	xml.AddValue(_T("iWindowShowCmd"),iWindowShowCmd,CMarkupEX::VALTYPE_DEC);
	xml.AddValue(_T("iWindowX"),iWindowX,CMarkupEX::VALTYPE_DEC);
	xml.AddValue(_T("iWindowY"),iWindowY,CMarkupEX::VALTYPE_DEC);
	xml.AddValue(_T("iWindowWidth"),iWindowWidth,CMarkupEX::VALTYPE_DEC);
	xml.AddValue(_T("iWindowHeight"),iWindowHeight,CMarkupEX::VALTYPE_DEC);

	xml.AddElem(_T("MostRecentFiles"));
	xml.IntoElem();
	for(int i = 0; i < iMostRecentMaximum; i++ )
		if(!strMostRecent[i].IsEmpty())
			xml.AddElem(_T("FileEntry"),strMostRecent[i]);
	xml.OutOfElem();

	xml.AddElem(_T("MostRecentTables"));
	xml.IntoElem();
	for(int i = 0; i < iMostRecentTableMaximum; i++ )
		if(!strMostRecentTable[i].IsEmpty())
			xml.AddElem(_T("TableEntry"),strMostRecentTable[i]);

	xml.OutOfElem();

	if(!xml.Save(xml_name))
		MessageBox(_T("Preferences could not be saved to the configuration file."), _T("Configuration error:"), MB_OK | MB_ICONERROR );

	return 0;
}

void Translhextion::draw_border_client_rect (HDC hdc)
{
	int retrieved_device_context = FALSE;
	if (hdc == 0)
	{
		hdc = GetDC (*this);
		retrieved_device_context = TRUE;
	}
	RECT r;
	r.left = 0;
	r.top = cClientYPos;
	r.right = cClientXDim;
	r.bottom = cClientYDim;
	DrawEdge (hdc, &r, EDGE_SUNKEN, BF_RECT);
	if (retrieved_device_context)
	{
		ReleaseDC (*this, hdc);
	}
}


int Translhextion::on_deletekey ()
{
	iCutMode = BST_UNCHECKED;
	return edit_cut ();
}


int Translhextion::on_backspace ()
{
	if (iInsertMode && !bReadOnly)
	{
		
		if (iCurrentByte > 0)
		{
			if (FileBuffer.RemoveAt (iCurrentByte-1, 1) == TRUE)
			{
				//vChanges.remove(iCurrentByte-1);
				vChanges.erase(vChanges.begin()+iCurrentByte-1);
				iCurrentByte--;
				update_size_change ();
				iFileChanged = TRUE;
			}
			else
				MessageBox (_T("Byte could not be removed."), _T("Editing error:"), MB_OK | MB_ICONERROR);
			
		}
	}
	else
	{
		
		if (iCurrentByte>0)
			iCurrentByte--;
		repaint ();
	}
	return 1;
}


int Translhextion::make_font ()
{
	if (hFont != NULL) DeleteObject (hFont);
	HDC hdc = GetDC (*this);
	int nHeight = -MulDiv(iFontSize, GetDeviceCaps(hdc, LOGPIXELSY), 72);
	ReleaseDC (*this, hdc);

	hFont = CreateFont (nHeight,0,0,0,0,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,
		CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,FIXED_PITCH | FF_DONTCARE,_T("Courier"));
	return 1;
}

int Translhextion::make_jfont()
{
	if (hfJap != NULL)
		DeleteObject (hfJap);
	HDC hdc = GetDC (*this);
	int nHeight2 = -MulDiv(iFontSize, GetDeviceCaps(hdc, LOGPIXELSY), 72);
	ReleaseDC (*this, hdc);

	hfJap = CreateFont (nHeight2,0,0,0,0,0,0,0,FS_JISJAPAN,OUT_DEFAULT_PRECIS,
		CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,FIXED_PITCH | FF_DONTCARE,_T("Courier"));
	return 1;
}


char Translhextion::TranslateAnsiToOem (TCHAR c)
{
	TCHAR sbuf[2];
	char dbuf[2];
	sbuf[0]=c;
	sbuf[1]=0;
	CharToOemBuff (sbuf, dbuf, 1);
	return dbuf[0];
}


int Translhextion::timer (WPARAM w, LPARAM l)
{
	if (!bSelected || !bTimerSet)
		return 0;

	if (iMouseY > cBufferY*cCharYDim)
	{
		
		if (iCurrentLine < (iNumlines-1))
			iCurrentLine++;
		update_vertical_scrollbar ();
		repaint ();
	}
	else if (iMouseY < 0)
	{
		
		if (iCurrentLine > 0)
			iCurrentLine--;
		update_vertical_scrollbar ();
		repaint ();
	}
	return 1;
}

int Translhextion::dropfiles( HANDLE hDrop )
{
	TCHAR lpszFile[ _MAX_PATH+1 ];
	DragQueryFile( (HDROP) hDrop, 0, lpszFile, _MAX_PATH+1 );
	DragFinish( (HDROP) hDrop ); 
	SetForegroundWindow( *this );
	if( iFileChanged == TRUE )
	{
		if( MessageBox (LoadString(IDS_NOTICE_DISCARD_CHANGES), LoadString(IDS_TITLE_NOTICE), MB_YESNO | MB_ICONQUESTION) == IDNO )
			return 0;
	}

	TCHAR lpszTarget[ MAX_PATH ];
	
	HRESULT hres = ResolveIt( *this, lpszFile, lpszTarget );
	if( SUCCEEDED( hres ) )
	{
		int ret = MessageBox(LoadString(IDS_NOTICE_LINK),
			LoadString(IDS_TITLE_NOTICE), MB_YESNOCANCEL | MB_ICONQUESTION );
		switch( ret )
		{
		case IDYES:
			if( load_file( lpszTarget ) )
			{
				iVerticalScrollMax = 0;
				iVerticalScrollPos = 0;
				iVerticalScrollInc = 0;
				iHorizontalScrollMax = 0;
				iHorizontalScrollPos = 0;
				iHorizontalScrollInc = 0;
				iCurrentLine = 0;
				iCurrentByte = 0;
				iCurrentNibble = 0;
				iFileSize = FileBuffer.Length();
				iFileChanged = FALSE;
				bFilestatusChanged = TRUE;
				update_size_change();
			}					
			break;

		case IDNO:
			if( load_file( lpszFile ) )
			{
				iVerticalScrollMax = 0;
				iVerticalScrollPos = 0;
				iVerticalScrollInc = 0;
				iHorizontalScrollMax = 0;
				iHorizontalScrollPos = 0;
				iHorizontalScrollInc = 0;
				iCurrentLine = 0;
				iCurrentByte = 0;
				iCurrentNibble = 0;
				iFileSize = FileBuffer.Length();
				iFileChanged = FALSE;
				bFilestatusChanged = TRUE;
				update_size_change();
			}					
			break;

		case IDCANCEL:
			break;
		}
	}
	else
	{
		if( load_file( lpszFile ) )
		{
			iVerticalScrollMax = 0;
			iVerticalScrollPos = 0;
			iVerticalScrollInc = 0;
			iHorizontalScrollMax = 0;
			iHorizontalScrollPos = 0;
			iHorizontalScrollInc = 0;
			iCurrentLine = 0;
			iCurrentByte = 0;
			iCurrentNibble = 0;
			iFileSize = FileBuffer.Length();
			iFileChanged = FALSE;
			bFilestatusChanged = TRUE;
			update_size_change();
		}
	}
	return 1;
}

VOID Translhextion::MakeChartMenu() 
{ 
    //HBITMAP hbmpPie;    // handle to pie chart bitmap   
    //HBITMAP hbmpLine;   // handle to line chart bitmap  
    HBITMAP hbmpBar;    // handle to bar chart bitmap   
    HMENU hmenuMain;    // handle to main menu          
    HMENU hmenuChart;   // handle to Chart menu  
 
    // Load the pie, line, and bar chart bitmaps from the 
    // resource-definition file. 
 
    //hbmpPie = LoadBitmap(hInstance, MAKEINTRESOURCE(PIE)); 
    //hbmpLine = LoadBitmap(hInstance, MAKEINTRESOURCE(LINE)); 
    hbmpBar = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_MAINTOOLBAR32)); 
 
    // Create the Chart menu and add it to the menu bar. 
    // Append the Pie, Line, and Bar menu items to the Chart 
    // menu. 
 
    hmenuMain = GetMenu(*this); 
    hmenuChart = CreatePopupMenu(); 
    AppendMenu(hmenuMain, MF_STRING | MF_POPUP, (UINT) hmenuChart, _T("Chart")); 
    //AppendMenu(hmenuChart, MF_BITMAP, IDM_PIE, (LPCTSTR) hbmpPie); 
    //AppendMenu(hmenuChart, MF_BITMAP, IDM_LINE,(LPCTSTR) hbmpLine); 
    AppendMenu(hmenuChart, MF_BITMAP, IDM_OPEN, (LPCTSTR) hbmpBar); 
 
    return;
} 
 
VOID Translhextion::MakeLineMenu(HPEN *phpen, HBITMAP *phbmp) 
{ 
    HMENU hmenuLines;       // handle to Lines menu      
    HMENU hmenu;            // handle to main menu              
    COLORREF crMenuClr;     // menu-item background color       
    HBRUSH hbrBackground;   // handle to background brush       
    HBRUSH hbrOld;          // handle to previous brush         
    WORD wLineX;            // width of line bitmaps            
    WORD wLineY;            // height of line bitmaps           
    HDC hdcMain;            // handle to main window's DC       
    HDC hdcLines;           // handle to compatible DC          
    HBITMAP hbmpOld;        // handle to previous bitmap        
    int i;                  // loop counter                     
 
    // Create the Lines menu. Add it to the menu bar.  
 
    hmenu = GetMenu(*this); 
    hmenuLines = CreatePopupMenu(); 
    AppendMenu(hmenu, MF_STRING | MF_POPUP, (UINT) hmenuLines, _T("&Lines")); 
 
    // Create a brush for the menu-item background color.  
    crMenuClr = GetSysColor(COLOR_MENU); 
    hbrBackground = CreateSolidBrush(crMenuClr); 
 
    // Create a compatible device context for the line bitmaps, 
    // and then select the background brush into it. 
 
    hdcMain = GetDC(*this); 
    hdcLines = CreateCompatibleDC(hdcMain); 
    hbrOld = (HBRUSH)SelectObject(hdcLines, hbrBackground); 
 
    // Get the dimensions of the check-mark bitmap. The width of 
    // the line bitmaps will be five times the width of the 
    // check-mark bitmap. 
 
    wLineX = GetSystemMetrics(SM_CXMENUCHECK) * (WORD) 5; 
    wLineY = GetSystemMetrics(SM_CYMENUCHECK); 
 
    // Create the bitmaps and select them, one at a time, into the 
    // compatible device context. Initialize each bitmap by 
    // filling it with the menu-item background color. 
    for (i = 0; i < 5/*CPENS*/; i++) 
    { 
        phbmp[i] = (HBITMAP)CreateCompatibleBitmap(hdcMain, wLineX, wLineY); 
        if (i == 0) 
            hbmpOld = (HBITMAP)SelectObject(hdcLines, phbmp[i]); 
        else 
            SelectObject(hdcLines, phbmp[i]); 
        ExtFloodFill(hdcLines, 0, 0, crMenuClr, FLOODFILLBORDER); 
    } 
 
    // Create the pens.  
 
    phpen[0] = CreatePen(PS_SOLID, 1, RGB(0, 0, 0)); 
    phpen[1] = CreatePen(PS_DOT, 1, RGB(0, 0, 0)); 
    phpen[2] = CreatePen(PS_DASH, 1, RGB(0, 0, 0)); 
    phpen[3] = CreatePen(PS_DASHDOT, 1, RGB(0, 0, 0)); 
    phpen[4] = CreatePen(PS_DASHDOTDOT, 1, RGB(0, 0, 0)); 
 
    // Select a pen and a bitmap into the compatible device 
    // context, draw a line into the bitmap, and then append 
    // the bitmap as an item in the Lines menu. 
 
    for (i = 0; i < 5/*CPENS*/; i++) 
    { 
        SelectObject(hdcLines, phbmp[i]); 
        SelectObject(hdcLines, phpen[i]); 
        MoveToEx(hdcLines, 0, wLineY / 2, NULL); 
        LineTo(hdcLines, wLineX, wLineY / 2); 
        AppendMenu(hmenuLines, MF_BITMAP, i + 1, (LPCTSTR) phbmp[i]); 
    } 
 
    // Release the main window's device context and destroy the 
    // compatible device context. Also, destroy the background 
    // brush. 
 
    ReleaseDC(*this, hdcMain); 
    SelectObject(hdcLines, hbrOld); 
    DeleteObject(hbrBackground); 
    SelectObject(hdcLines, hbmpOld); 
    DeleteDC(hdcLines); 
 
    return; 
}

LRESULT Translhextion::OnMessage(UINT iMsg, WPARAM wParam, LPARAM lParam)
{
	//if( bInsertingHex )
	//{
	//	switch( iMsg )
	//	{
	//		case WM_SIZE: case WM_KILLFOCUS: case WM_LBUTTONDOWN:
	//		case WM_LBUTTONUP: case WM_VSCROLL:
	//		case WM_HSCROLL: case WM_COMMAND: case WM_DROPFILES:
	//		case WM_CLOSE: case WM_DESTROY:
	//			bInsertingHex = FALSE;
	//			break;

	//		case WM_KEYDOWN:
	//			switch( wParam )
	//			{
	//			case VK_END:
	//			case VK_HOME:
	//			case VK_LEFT:
	//			case VK_RIGHT:
	//			case VK_UP:
	//			case VK_DOWN:
	//			case VK_PRIOR:
	//			case VK_NEXT:
	//				bInsertingHex = FALSE;
	//				break;

	//			default:
	//				break;
	//			}

	//		default:
	//			break;
	//	}
	//}

	switch( iMsg )
	{
	case WM_ACTIVATE:
		SendMessage(m_Frame,WM_ACTIVATE,wParam,lParam);
		break;
	/* menu functions */
	case WM_DRAWITEM:
		m_Menu.OnDrawItem((LPDRAWITEMSTRUCT) lParam);
		return TRUE;
	case WM_MEASUREITEM: 
		m_Menu.OnMeasureItem((int)wParam,(LPMEASUREITEMSTRUCT) lParam); 
		return TRUE;
	//case WM_INITMENU:
	//	if(!SubMenuSystem((HMENU)wParam))
	//		m_Menu.OnInitMenuPopup((HMENU)wParam,TRUE);
	//	return 0;
	case WM_INITMENUPOPUP:
		initmenupopup( wParam, lParam );
		if(!SubMenuSystem((HMENU)wParam))
			m_Menu.OnInitMenuPopup((HMENU)wParam,FALSE);
		return TRUE;
	case WM_UNINITMENUPOPUP:
		m_Menu.OnUnInitMenuPopup((HMENU)wParam);
		return 0;
	//case WM_ENTERMENULOOP:
	//	OutputDebugString(_T("Enter Menu Loop\n"));
	//	return 0;
	//case WM_NCPAINT:
	//	DefWindowProc(hWnd, iMsg, wParam, lParam);
	//	{
	//		MENUBARINFO menuInfo = {sizeof(MENUBARINFO)};
	//		GetMenuBarInfo(*this,OBJID_MENU, 0, &menuInfo);
	//		HDC hdc = GetDCEx(*this, (HRGN)wParam, DCX_WINDOW | DCX_INTERSECTRGN);
	//		CBrush b(RGB(255,0,0));
	//		FillRect(hdc,&menuInfo.rcBar,b);
	//		ReleaseDC(*this,hdc);
	//	}
	//	return 0;
	//
	case WM_SIZE:
		resize_window( LOWORD( lParam ), HIWORD( lParam ) );
		return 0;
	//case WM_ERASEBKGND:
	//	return TRUE;
	case WM_COMMAND:
		OnCommand(wParam,lParam);
		break;
	//case WM_TIMER:
	//	timer( wParam, lParam );
	//	return 0;
	//case WM_DROPFILES:
	//	dropfiles( (HANDLE) wParam ); 
	//	return 0;
	//case WM_CLOSE:
	//	close();
	//	return 0;
	//case WM_DESTROY:
	//	m_Menu.OnDestroy();
	//	destroy_window();
	//	PostQuitMessage( 0 );
	//	return 0;
	default:
		return DefWindowProc(hWnd, iMsg, wParam, lParam);
	}

	return FALSE;
}

int	Translhextion::translate_binary_to_text( _tstring& dest, char* src, int len )
{
	int iDestinationLength = byte_to_bytecode_destinationlength( src, len );
	TCHAR * cBuf = new TCHAR[iDestinationLength];
	strToReplaceData = (_tstring) cBuf;
	delete [] cBuf;
	if( (TCHAR*) strToReplaceData.c_str() != NULL )
	{
		translate_bytes_to_bytecode( (TCHAR*) strToReplaceData.c_str(), (unsigned char*) src, len );
		return TRUE;
	}
	else
		return FALSE;
}

int Translhextion::find_and_select_data( _tstring& finddata, int finddir, int do_repaint, int (*cmp) (u8*))
{
	u8* tofind;
	int iDestinationLength = bytecode_translate(&tofind, 
		(TCHAR*)finddata.c_str(), 
		finddata.length(), 
		iCharacterSet, 
		iBinaryMode 
		);

	int i;
	if( finddir == 1 )
	{
		i = find_bytes( &(FileBuffer[iCurrentByte + 1]),
			FileBuffer.Length() - iCurrentByte - 1,
			tofind,	iDestinationLength, 1, src_helper.GetSearchMethod() /*cmp*/ );
		if( i != -1 )
			iCurrentByte += i + 1;
	}
	else
	{
		i = find_bytes( &(FileBuffer[0]),
					min( iCurrentByte + (iDestinationLength - 1), FileBuffer.Length() ),
					tofind, iDestinationLength, -1, src_helper.GetSearchMethod() /*cmp*/ );
		if( i != -1 )
			iCurrentByte = i;
	}

	if( i != -1 )
	{
		bSelected = TRUE;
		iStartOfSelection = iCurrentByte;
		iEndOfSelection = iCurrentByte + iDestinationLength - 1;
		if( do_repaint )
		{
			adjust_view_for_selection();
			repaint();
		}
	}
	else
	{
		if( tofind != NULL )
			delete [] tofind;
		return FALSE;
	}

	if( tofind != NULL )
		delete [] tofind;
	return TRUE;
}

int Translhextion::replace_selected_data( _tstring& replacedata, int do_repaint )
{
	if( bSelected )
	{
		if( replacedata == L"")
		{
			if( FileBuffer.Replace( iGetStartOfSelection(),
				iGetEndOfSelection() - iGetStartOfSelection() + 1,
				NULL, 0	) == TRUE )
			{
				long m = iGetStartOfSelection();
				for(m = m;m<iGetEndOfSelection();m++)
					//vChanges.remove(m);
					vChanges.erase(vChanges.begin()+m);
				bSelected = FALSE;
				bFilestatusChanged = TRUE;
				iFileChanged = TRUE;
				iCurrentByte = iStartOfSelection;
				if( do_repaint )
				{
					update_size_change();
					repaint();
				}
				return TRUE;
			}
			else
			{
				MessageBox(_T("Selection could not be replaced."), _T("Replace error:"), MB_OK | MB_ICONERROR );
				return FALSE;
			}
		}

		if( iPasteAsText )
		{
			int a = iGetStartOfSelection(), b = iGetEndOfSelection();
			if( FileBuffer.Replace( iGetStartOfSelection(),
				iGetEndOfSelection() - iGetStartOfSelection() + 1,
				(unsigned char*) (char*) replacedata.c_str(), replacedata.length()
				) == TRUE )
			{
				long m = iGetStartOfSelection();
				for(m = m;m<iGetEndOfSelection();m++)
					vChanges[m] = COLORCHANGE;
				iEndOfSelection = iStartOfSelection + replacedata.length() - 1;
				if( do_repaint )
				{
					update_size_change();
					repaint();
				}
				bFilestatusChanged = TRUE;
				iFileChanged = TRUE;
				return TRUE;
			}
			else
			{
				MessageBox(_T("Replace failure."), _T("Replace error:"), MB_OK | MB_ICONERROR );
				return FALSE;
			}
		}
		else
		{
			FileVector<char> out;
			if( translate_text_to_binary( replacedata, out ) == TRUE )
			{
				int a = iGetStartOfSelection(), b = iGetEndOfSelection();
				if( FileBuffer.Replace( iGetStartOfSelection(),
					iGetEndOfSelection() - iGetStartOfSelection() + 1,
					(unsigned char*) (char*) out, out.Length()
					) == TRUE )
				{
					long m = iGetStartOfSelection();
					for(m = m;m<iGetEndOfSelection();m++)
					vChanges[m] = COLORCHANGE;
					bFilestatusChanged = TRUE;
					iFileChanged = TRUE;
					iEndOfSelection = iStartOfSelection + out.Length() - 1;
					if( do_repaint )
					{
						update_size_change();
						repaint();
					}
					return TRUE;
				}
				else
				{
					MessageBox(_T("Replace failure."), _T("Replace error:"), MB_OK | MB_ICONERROR );
					return FALSE;
				}
			}
			else
			{
				MessageBox(_T("Text could not be translated to binary."), _T("Replace error:"), MB_OK | MB_ICONERROR );
				return FALSE;
			}
		}
	}
	else
	{
		MessageBox(LoadString(IDS_NOTICE_SEL_REP_DATA), LoadString(IDS_TITLE_NOTICE), MB_OK | MB_ICONINFORMATION );
	}
	return FALSE;
}

int Translhextion::translate_text_to_binary( _tstring& in, FileVector<char>& out )
{
	u8* pcOut;
	int iDestinationLength = bytecode_translate( &pcOut,
		(TCHAR*) in.c_str(),
		in.length(),
		iCharacterSet,
		iBinaryMode
		);

	if( iDestinationLength != 0 )
	{
		out.Adopt((char*)pcOut, iDestinationLength - 1, iDestinationLength );
		return TRUE;
	}
	else
	{
		

	}
	return FALSE;
}

static TCHAR input(const int& index)
{
	return cBuf[index];
}

TCHAR file(const int& index)
{
	TCHAR x=0;
	_lseek(FWFile, index, SEEK_SET);
	_read(FWFile,&x,1);
	return x;
}
int Translhextion::find_byte_pos (TCHAR* src, TCHAR c)
{
	int i=0;
	while (src[i] != c)
	{
		i++;
	}
	return i;
}

UINT Translhextion::OnCommand(WPARAM wParam, LPARAM lParam)
{
	int cmd=LOWORD(wParam);
	HMENU hMenu = GetMenu (*this);

	switch( cmd )
	{
	case IDA_BACKSPACE:
		on_backspace ();
		break;
	case IDA_DELETEKEY:
		on_deletekey ();
		break;
	case IDA_SELECTPAGEDOWN:
	case IDA_SELECTPAGEUP:
	case IDA_SELECTSTARTOFLINE:
	case IDA_SELECTENDOFLINE:
	case IDA_SELECTSTARTOFFILE:
	case IDA_SELECTENDOFFILE:
	case IDA_SELECTLEFT:
	case IDA_SELECTRIGHT:
	case IDA_SELECTUP:
	case IDA_SELECTDOWN:
		select_with_arrowkeys (cmd);
		break;
	case IDM_IME:
		{
			if(bTableLoaded && bTableActive && !bReadOnly)
			{
				/*extern Translhextion mainwindow;*/
				while(!bIMEDone)
				{
					bInsertMode = iInsertMode&1 ? true : false;
					DialogBox(hInstance, MAKEINTRESOURCE (IDD_IMEBAR),*this,IMEBarDialogProc);
					if((int)vIMEBytes.size() != 0 && (iInsertMode || (int)vIMEBytes.size() + iCurrentByte > FileBuffer.Length()))
					{
						string bs;
						SetCursor (LoadCursor (NULL, IDC_WAIT));
						int k = 0;
						for(k = 0;k<(int)vIMEBytes.size();k++)
						{
							bs += char_hex(vIMEBytes[k]);
						}
						char* pcPastestring;
						int iDestinationLength = bs.length();
						pcPastestring = new char[ iDestinationLength ];
						memcpy( pcPastestring, bs.c_str(), iDestinationLength );
						if(!FileBuffer.InsertExpandOn(iCurrentByte,(unsigned char*)pcPastestring,0,iDestinationLength))
						{
							delete [] pcPastestring;
							SetCursor (LoadCursor (NULL, IDC_ARROW));
							MessageBox(LoadString(IDS_PASTE_OUT_OF_MEMORY), LoadString(IDS_TITLE_PASTE_ERROR), MB_OK | MB_ICONERROR);
							update_size_change ();
							return FALSE;
						}
						long m = iCurrentByte;
						for(m = m;m<iCurrentByte+iDestinationLength;m++)
							vChanges.insert(vChanges.begin()+m,COLORCHANGE);
						delete [] pcPastestring;
						iFileChanged = TRUE;
						bFilestatusChanged = TRUE;
					}
					else if (vIMEBytes.size() != 0)
					{
						SetCursor (LoadCursor (NULL, IDC_WAIT));
						int k = iCurrentByte;
						for(k = k;k<iCurrentByte + (int)vIMEBytes.size();k++)
						{
							FileBuffer[k] = char_hex(vIMEBytes[k-iCurrentByte]);
							vChanges[k] = COLORCHANGE;
						}
						iFileChanged = TRUE;
						bFilestatusChanged = TRUE;
					}
					else
					{
						bIMEDone = true;
					}
					iCurrentByte = iCurrentByte + vIMEBytes.size();
					vIMEBytes = vEmpty;
					SetCursor (LoadCursor (NULL, IDC_ARROW));
					adjust_view_for_selection ();
					/*mainwindow.*/repaint();
				}
				bIMEDone = false;
				
			}
			break;
		}
	case IDM_INTERNALSTATUS:
		{
			GString cBuf, buf2;
			//sprintf (cBuf, "");
			buf2.Format(_T("# of bytes in current file: %d\n"), FileBuffer.GetSize ());
			//strcat (cBuf, buf2);
			buf2.Format(_T("# of lines in current file: %d\n"), iNumlines);
			//strcat (cBuf, buf2);
			buf2.Format(_T("Current Byte #: %d\n\n"), iCurrentByte);
			cBuf+=buf2;

			if(bTableLoaded)
				cBuf+=_T("Table Loaded: YES\n");
			else
				cBuf+=_T("Table Loaded: NO\n");
			if(bTableActive)
				cBuf+=_T("Table Active: YES\n\n");
			else
				cBuf+=_T("Table Active: NO\n\n");
			buf2.Format(_T("Tokens in table: %d\n\n"), iRealTable);
			cBuf+=buf2;
			buf2.Format(_T("# of successful script dumps this run: %d\n"), dumps);
			cBuf+=buf2;
			buf2.Format(_T("# of successful script insertions this run: %d\n"), inserts);
			cBuf+=buf2;
			buf2.Format(_T("# of successful script optimizations this run: %d\n"), optimized);
			cBuf+=buf2;
	
			buf2.Format(_T("%s status:"),sName);
			MessageBox (cBuf, buf2, MB_OK);
			break;
		}
	case IDM_CHANGE_MODE:
		character ('\t');
		break;
	//FILE	
	case IDM_EXIT:
		SendMessage (*this, WM_CLOSE, 0, 0);
		break;
	case IDM_NEW:
		_New ();
		break;
	case IDM_OPEN:
		open ();
		break;
	case IDM_SAVE:
		save ();
		break;
	case IDM_SAVE_AS:
		save_as ();
		break;
	case IDM_EDIT_READONLYMODE:
		if( bReadOnly == FALSE )
			bReadOnly = TRUE;
		else
			bReadOnly = FALSE;
		update_size_change();
		break;
	case IDM_PARTIAL_OPEN:
		open_partially ();
		break;
	case IDM_REVERT:
		revert();
		break;
	case IDM_DELETEFILE:
		deletefile();
		break;
	case IDM_PROPERTIES:
		properties ();
		break;
	case IDM_APPLYTEMPLATE:
		apply_template();
		break;
	case IDM_OPEN_TEXT:
		summon_text_edit();
		break;
	case IDM_MRU1:
	case IDM_MRU2:
	case IDM_MRU3:
	case IDM_MRU4:
	case IDM_MRU5:
	case IDM_MRU6:
	case IDM_MRU7:
	case IDM_MRU8:
	case IDM_MRU9:
		most_recent_selection (cmd);
		break;
	//SELECTION
	case IDM_EDIT_CUT:
		iCutMode = BST_CHECKED;
		edit_cut ();
		break;
	case IDM_EDIT_COPY:
		if(bThingyView)
		{
			thingy_copy();
		}
		else
		{
			edit_copy ();
		}
		break;
	case IDM_EDIT_PASTE:
		fast_paste ();
		break;
	case IDM_PASTE_WITH_DLG:
		edit_paste ();
		break;
	case IDM_SELECT_ALL:
		select_all ();
		break;
	case IDM_SELECT_BLOCK:
		select_block ();
		break;
	case IDM_FILL_WITH:
		fill_with();
		break;
	case IDM_COPY_HEXDUMP:
		copy_hexdump ();
		break;
	case IDM_SAVESELAS:
		save_selection_as();
		break;

	//OFFSET
	case IDM_GO_TO:
		_Goto();
		break;
	case IDM_READFLOAT:
		{
			GString cBuf, buf2;
			float floatval;
			if (FileBuffer.Length()-iCurrentByte >= 4)
			{
				if (iBinaryMode == LITTLE_ENDIAN)
				{
					floatval = *((float*)&(FileBuffer[iCurrentByte]));
				}
				else // BIG_ENDIAN
				{
					char* pf = (char*) &floatval;
					int i;
					for (i=0; i<4; i++)
						pf[i] = FileBuffer[iCurrentByte+3-i];
				}
				cBuf.Format(_T("float size value:\n%f\n"), floatval);
			}
			else
				cBuf.Format(_T("Not enough space for float size value.\n"));
			double dval;
			if (FileBuffer.Length()-iCurrentByte >= 8)
			{
				if (iBinaryMode == LITTLE_ENDIAN)
				{
					dval = *((double*)&(FileBuffer[iCurrentByte]));
				}
				else // BIG_ENDIAN
				{
					char* pd = (char*) &dval;
					int i;
					for (i=0; i<8; i++)
						pd[i] = FileBuffer[iCurrentByte+7-i];
				}
				buf2.Format(_T("\ndouble size value:\n%g\n"), dval);
				cBuf+=buf2;
			}
			else
			{
				buf2.Format(_T("\nNot enough space for double size value.\n"));
				cBuf+=buf2;
			}
			
			MessageCopyBox (NULL, (LPTSTR)(LPCTSTR)cBuf, _T("Floating point values:"), MB_ICONINFORMATION, *this);
			break;
		}
	case IDM_EDIT_MANIPULATEBITS:
		manipulate_bits ();
		break;
	case IDM_COMPARE:
		compare ();
		break;
	//INSERT
	case IDA_INSERTMODETOGGLE:
		toggle_insertmode ();
		break;
	case IDM_EDIT_ENTERDECIMALVALUE:
		edit_enterdecimalvalue ();
		break;
	case IDM_EDIT_APPEND:
		edit_append ();
		break;
	case IDM_INSERTFILE:
		insertfile();
		break;
	//SEARCH
	case IDM_FIND:
		find ();
		break;
	case IDM_HEXFIND:
		find_hex();
		break;
	case IDM_TABLEFIND:
		find_with_table();
		break;

	case IDM_FINDNEXT:
		{
			if(bLastSearchType == 0)
				findnext();
			if(bLastSearchType == 1)
				findnext_relative();
		}
		break;
	case IDM_FINDPREV:
		{
			if(bLastSearchType == 0)
				findprev();
			if(bLastSearchType == 1)
				findprev_relative();
		}
		break;
	case IDM_REPLACE:
		replace();
		break;
	case IDM_TABLEREPLACE:
		replace_with_table();
		break;
	case IDM_RELATIVEFIND:
		search_relative ();
		break;
	case IDM_RELATIVESCAN:
		scan_relative();
		break;
	case IDM_RELATIVESCANVAL:
		value_scan_relative();
		break;
	//BOOKMARK
	case IDM_ADDBOOKMARK:
		add_bookmark ();
		break;
	case IDM_REMOVE_BKM:
		remove_bookmark ();
		break;
	case IDM_CLEARALL_BMK:
		clear_all_bookmark ();
		break;
	case IDM_BOOKMARK1:
	case IDM_BOOKMARK2:
	case IDM_BOOKMARK3:
	case IDM_BOOKMARK4:
	case IDM_BOOKMARK5:
	case IDM_BOOKMARK6: 
	case IDM_BOOKMARK7:
	case IDM_BOOKMARK8:
	case IDM_BOOKMARK9: 
		goto_bookmark (cmd);
		break;
	//SCRIPT
	case IDM_OPEN_TABLE:
		open_table();
		break;
	case IDM_MRTABLE1:
	case IDM_MRTABLE2:
	case IDM_MRTABLE3:
	case IDM_MRTABLE4:
	case IDM_MRTABLE5:
		most_recent_table_selection (cmd);
		break;
	case IDM_TABLE_CONVERT:
		convert_table();
		break;
	case IDM_SCRIPT_DUMP:
		script_dump();
		break;
	case IDM_REPLACE_SCRIPT:
		replace_script();
		break;
	case IDM_OPTIMIZESCRIPT:
		optimize_script_file();
		break;
	case IDM_SCRIPTMARK1:
	case IDM_SCRIPTMARK1 + 1:
	case IDM_SCRIPTMARK1 + 2: 
	case IDM_SCRIPTMARK1 + 3:
	case IDM_SCRIPTMARK1 + 4:
	case IDM_SCRIPTMARK1 + 5: 
	case IDM_SCRIPTMARK1 + 6:
	case IDM_SCRIPTMARK1 + 7:
	case IDM_SCRIPTMARK1 + 8: 
		iDumpStart = vScriptDumps[cmd - IDM_SCRIPTMARK1].start;
		iDumpEnd = vScriptDumps[cmd - IDM_SCRIPTMARK1].end;
		script_dump();
		break;
	//OPTIONS
	case IDM_VIEW_SETTINGS:
		view_settings ();
		break;
	case IDM_COLOR_SETTINGS:
		color_settings(); 
		break;
	case IDM_BINARYMODE:
		binarymode ();
		break;
	//case IDM_OFFSETMODE:
	//	offsetmode();
	//	break;
	//SCROLL
	case IDM_HIDE_HEX:
		if(bHideHex)
		{
			bHideHex = false;
			ShowCaret( *this );
		}
		else
		{
			bHideHex = true;
			HideCaret( *this );
		}
		mainwindow.repaint();
		mainwindow.update_size_change();
		break;

	case IDM_SCROLL_LEFT:
		if (iHorizontalScrollPos > 0)
		{
			iHorizontalScrollPos--;
			update_horizontal_scrollbar ();
			repaint ();
		}
		break;
	
	case IDM_SCROLL_RIGHT:
		if (iHorizontalScrollPos < iHorizontalScrollMax)
		{
			iHorizontalScrollPos++;
			update_horizontal_scrollbar ();
			repaint();
		}
		break;
	case IDM_SCROLL_UP:
		if (iCurrentLine > 0)
		{
			iCurrentLine--;
			update_vertical_scrollbar ();
			repaint ();
		}
		break;

	case IDM_SCROLL_DOWN:
		if (iCurrentLine < iNumlines-1)
		{
			iCurrentLine++;
			update_vertical_scrollbar ();
			repaint ();
		}
		break;
	case IDM_TOP:
		iCurrentByte = iCurrentLine = iCurrentNibble = 0;
		adjust_view_for_cursor ();
		update_vertical_scrollbar ();
		bSelected = FALSE;
		repaint();
		break;
	case IDM_BOTTOM:
	{
		iCurrentByte = FileBuffer.Upper()+1;
		iCurrentNibble = 1;
		iCurrentLine = (iCurrentByte / iBytesPerLine)-(cBufferY-1); 
		if (iCurrentLine < 0)
			iCurrentLine = 0;
		adjust_view_for_cursor ();
		update_vertical_scrollbar ();
		bSelected = FALSE;
		repaint();
		break;
	}
	//HELP
	case IDM_HELP_TOPICS:
		{
  			HINSTANCE hi = ShellExecute( *this, _T("open"), (sWindowsPath + _T("\\HH.EXE")).c_str(), (sAppPath + sName + _T(".chm")).c_str(), NULL, SW_SHOWNORMAL );
			if( (int) hi <= 32 )
				MessageBox((_T("HH.EXE was not found in ") + sWindowsPath + _T(".  HH.EXE is required for HTML help to function.")).c_str(), _T("Help error:"), MB_OK | MB_ICONERROR );
		}
		break;
	case IDM_ABOUT:
	{
		//DialogBox (hInstance, MAKEINTRESOURCE (IDD_ABOUTDIALOG), *this, (DLGPROC) AboutDialogProc);
		CAboutDlg dlg(*this);
		dlg.DoModal();
		break;
	}
	default:
		return TRUE;
	//default:
	//	{
	//		GString cBuf;
	//		cBuf.Format(_T("Unknown COMMAND_ID %d."), cmd);
	//		MessageBox (*this, cBuf, _T("Command error:"), MB_OK);
	//	}
	//	break;
	}
	return FALSE;
}

int Translhextion::initmenupopup( WPARAM w, LPARAM l )
{
	//FILE
	if( l == 0 )
	{
		//NEW
		// "New file" is always possible.
		EnableMenuItem( (HMENU) w, IDM_NEW, MF_ENABLED );

		//OPEN
		// "Open" is always allowed.
		EnableMenuItem( (HMENU) w, IDM_OPEN, MF_ENABLED );

		//OPEN PARTIALLY
		//Open Partially" is always allowed.
		EnableMenuItem( (HMENU) w, IDM_PARTIAL_OPEN, MF_ENABLED );

		//REVERT
		//Revert is allowed when the file has been saved, changed and is not in partial open mode
		EnableMenuItem( (HMENU) w, IDM_REVERT, ((!bFileNeverSaved && iFileChanged && !bPartialOpen)?MF_ENABLED:MF_GRAYED));

		//SAVE
		// "Save" is only possible if the current file has a name.
		if( !bFileNeverSaved )
			EnableMenuItem( (HMENU) w, IDM_SAVE, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDM_SAVE, MF_GRAYED );

		//SAVE AS
		// "Save as" is always possible.
		EnableMenuItem( (HMENU) w, IDM_SAVE_AS, MF_ENABLED );

		//READ-ONLY TOGGLE
		// "Read-only mode" is always allowed.
		EnableMenuItem( (HMENU) w, IDM_EDIT_READONLYMODE, MF_ENABLED );
		if( bReadOnly )
			CheckMenuItem( (HMENU) w, IDM_EDIT_READONLYMODE, MF_CHECKED );
		else
			CheckMenuItem( (HMENU) w, IDM_EDIT_READONLYMODE, MF_UNCHECKED );
		
		//CURRENT FILE
		
			//DELETE FILE
			//Delete file is allowed when the file has been saved and read only mode is off
			EnableMenuItem( GetSubMenu((HMENU) w,CURFPOS), IDM_DELETEFILE, ((!bFileNeverSaved && !bReadOnly)?MF_ENABLED:MF_GRAYED) );

			//PROPERTIES
			// "File properties" is always allowed.
			EnableMenuItem( GetSubMenu((HMENU) w,CURFPOS), IDM_PROPERTIES, MF_ENABLED );

			//APPLY TEMPLATE
			// "Apply template" is allowed if the cursor is on a byte
			// and there is no selection going on.
			if( iCurrentByte <= FileBuffer.Upper() && !bSelected )
				EnableMenuItem( GetSubMenu((HMENU) w,CURFPOS), IDM_APPLYTEMPLATE, MF_ENABLED );
			else
				EnableMenuItem( GetSubMenu((HMENU) w,CURFPOS), IDM_APPLYTEMPLATE, MF_GRAYED );
			
			//TEXT EDIT
			// "Open in text editor" is allowed if file has been saved before.
			if( !bFileNeverSaved )
				EnableMenuItem( GetSubMenu((HMENU) w,CURFPOS), IDM_OPEN_TEXT, MF_ENABLED );
			else
				EnableMenuItem( GetSubMenu((HMENU) w,CURFPOS), IDM_OPEN_TEXT, MF_GRAYED );


		//RECENT FILES
			
			//RECENT FILES
			// Create the MRU list.
			make_most_recent_list( (HMENU) w );
		
		//EXIT
		// "Exit" is always allowed.
		EnableMenuItem( (HMENU) w, IDM_EXIT, MF_ENABLED );

	
	}
	//SELECTION
	else if( l == 1 )
	{
		//CUT
		// "Cut" is allowed if there is a selection or the cursor is on a byte.
		// It is not allowed in read-only and partial-open mode.
		if( ( bSelected || iCurrentByte <= FileBuffer.Upper() ) && !bReadOnly && !bPartialOpen )
			EnableMenuItem( (HMENU) w, IDM_EDIT_CUT, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDM_EDIT_CUT, MF_GRAYED );

		//COPY
		// "Copy" is allowed if there is a selection or the cursor is on a byte.
		if( bSelected || iCurrentByte <= FileBuffer.Upper() )
			EnableMenuItem( (HMENU) w, IDM_EDIT_COPY, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDM_EDIT_COPY, MF_GRAYED );

		//PASTE
		// "Paste" is allowed if the clipboard contains text,
		// there is no selection going on and read-only is disabled.
		if( !bReadOnly && !bSelected )
		{
			if( OpenClipboard( NULL ) )
			{
				HGLOBAL hClipMemory = GetClipboardData( CF_TEXT );
				if( hClipMemory != NULL )
					EnableMenuItem( (HMENU) w, IDM_EDIT_PASTE, MF_ENABLED );
				else
					EnableMenuItem( (HMENU) w, IDM_EDIT_PASTE, MF_GRAYED );
				CloseClipboard ();
			}
			else
			{
				// Clipboard could not be opened => can't paste.
				EnableMenuItem( (HMENU) w, IDM_EDIT_PASTE, MF_GRAYED );
			}
		}
		else
			EnableMenuItem( (HMENU) w, IDM_EDIT_PASTE, MF_GRAYED );

		//PASTE PREVIEW
		// "Paste with dialogue" is allowed if read-only is disabled and.
		// there is no selection going on.
		if( !bReadOnly && !bSelected )
			EnableMenuItem( (HMENU) w, IDM_PASTE_WITH_DLG, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDM_PASTE_WITH_DLG, MF_GRAYED );

		//DELETE KEY
		// "Delete" is allowed if there is a selection or the cursor is on a byte.
		// It is not allowed in read-only and partial-open mode.
		if( ( bSelected || iCurrentByte <= FileBuffer.Upper() ) && !bReadOnly && !bPartialOpen )
			EnableMenuItem( (HMENU) w, IDA_DELETEKEY, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDA_DELETEKEY, MF_GRAYED );

		//SELECT ALL
		// "Select All" is allowed if file is not empty.
		if( FileBuffer.Length() > 0 )
			EnableMenuItem( (HMENU) w, IDM_SELECT_ALL, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDM_SELECT_ALL, MF_GRAYED );

		//SELECT BLOCK
		// "Select block" is allowed if file is not empty.
		if( FileBuffer.Length() > 0 )
			EnableMenuItem( (HMENU) w, IDM_SELECT_BLOCK, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDM_SELECT_BLOCK, MF_GRAYED );

		//FILL SELECTION
		//"Fill with" is allowed if read-only is disabled, there is selection
		//going on and the file is not in partial-open mode
		EnableMenuItem( (HMENU) w, IDM_FILL_WITH, ((!bReadOnly && bSelected && !bPartialOpen)?MF_ENABLED:MF_GRAYED) );

		//HEXDUMP
		// Hexdump is only possible if the file isn't empty.
		if( FileBuffer.Length() > 0 )
			EnableMenuItem( (HMENU) w, IDM_COPY_HEXDUMP, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDM_COPY_HEXDUMP, MF_GRAYED );

		//SAVE SELECTION
		//Save selection as is allowed when selection is going on
		EnableMenuItem( (HMENU) w, IDM_SAVESELAS, (bSelected?MF_ENABLED:MF_GRAYED) );
	}
	//OFFSET
	else if( l == 2 )
	{
		//JUMP TO
		// "Go to" is allowed if the file isn't empty.
		if( FileBuffer.Length() > 0 )
			EnableMenuItem( (HMENU) w, IDM_GO_TO, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDM_GO_TO, MF_GRAYED );

		//GET FLOAT VALUE
		// "Get floating point value" is allowed if the cursor is on a byte
		// and there is no selection going on.
		if( iCurrentByte <= FileBuffer.Upper() && !bSelected )
			EnableMenuItem( (HMENU) w, IDM_READFLOAT, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDM_READFLOAT, MF_GRAYED );

		//MANIPULATE BITS
		// "Manipulate bits" is allowed if the cursor is on a byte, read-only is disabled
		// and there is no selection going on.
		if( !bReadOnly && iCurrentByte <= FileBuffer.Upper() && !bSelected )
			EnableMenuItem( (HMENU) w, IDM_EDIT_MANIPULATEBITS, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDM_EDIT_MANIPULATEBITS, MF_GRAYED );

		//COMPARE
		// "Compare from current offset" is allowed if the cursor is on a byte
		// and there is no selection going on.
		if( iCurrentByte <= FileBuffer.Upper() && !bSelected )
			EnableMenuItem( (HMENU) w, IDM_COMPARE, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDM_COMPARE, MF_GRAYED );
	}
	//INSERT
	else if( l == 3 )
	{
		//CHAR/HEX ENTERING MODE TOGGLE
		// "Change editing mode" is allowed when not Read-only.
		if( !bReadOnly )
			EnableMenuItem( (HMENU) w, IDM_CHANGE_MODE, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDM_CHANGE_MODE, MF_GRAYED );

		//INSERT/OVERWRITE MODE TOGGLE
		// "Toggle entering mode" is allowed if read-only is disabled.
		if( !bReadOnly )
			EnableMenuItem( (HMENU) w, IDA_INSERTMODETOGGLE, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDA_INSERTMODETOGGLE, MF_GRAYED );

		//ENTER DECIMAL VALUE
		// "Enter decimal value" is allowed if read-only is disabled, the file is not empty,
		// the cursor is on a byte and there is no selection going on.
		if( !bReadOnly && FileBuffer.Length() > 0 && iCurrentByte <= FileBuffer.Upper() && !bSelected )
			EnableMenuItem( (HMENU) w, IDM_EDIT_ENTERDECIMALVALUE, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDM_EDIT_ENTERDECIMALVALUE, MF_GRAYED );

		//INSERT BYTES AT END
		// "Append" is allowed if read-only is disabled and file is not
		// in partial-open mode and there is no selection going on.
		if( !bReadOnly && !bPartialOpen && !bSelected )
			EnableMenuItem( (HMENU) w, IDM_EDIT_APPEND, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDM_EDIT_APPEND, MF_GRAYED );

		//INSERT FILE
		//Insert file is allowed when read only mode is off & no selection
		EnableMenuItem( (HMENU) w, IDM_INSERTFILE, ((!bReadOnly && !bSelected)?MF_ENABLED:MF_GRAYED));
	}
	//SEARCH
	else if( l == 4 )
	{
		//FIND
		// "Find" is allowed if the file is not empty.
		if( FileBuffer.Length() > 0 )
		{
			EnableMenuItem( (HMENU) w, IDM_FIND, MF_ENABLED );
			EnableMenuItem( (HMENU) w, IDM_HEXFIND, MF_ENABLED );
		}
		else
		{
			EnableMenuItem( (HMENU) w, IDM_FIND, MF_GRAYED );
			EnableMenuItem( (HMENU) w, IDM_HEXFIND, MF_GRAYED );
		}

		//FIND USING TABLE
		// "Find with table" is allowed if file is not empty & if table is loaded and active
		if( FileBuffer.Length() > 0 && bTableLoaded && bTableActive)
			EnableMenuItem( (HMENU) w, IDM_TABLEFIND, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDM_TABLEFIND, MF_GRAYED );

		//FIND NEXT
		// "Find next" is allowed if the file is not empty,
		// and there is a findstring OR there is a selection
		// (which will be searched for).
		if( FileBuffer.Length() > 0 && ( src_helper.GetSearchData() /*pcFindDialogBuffer != NULL*/ || bSelected ) )
			EnableMenuItem( (HMENU) w, IDM_FINDNEXT, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDM_FINDNEXT, MF_GRAYED );

		//FIND PREVIOUS
		// "Find previous" is allowed if the file is not empty,
		// and there is a findstring OR there is a selection
		// (which will be searched for).
		if( FileBuffer.Length() > 0 && ( src_helper.GetSearchData() /*pcFindDialogBuffer != NULL*/ || bSelected ) )
			EnableMenuItem( (HMENU) w, IDM_FINDPREV, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDM_FINDPREV, MF_GRAYED );

		//REPLACE
		// "Replace" is allowed if the file is not empty and read-only is disabled.
		if( FileBuffer.Length() > 0 && !bReadOnly )
			EnableMenuItem( (HMENU) w, IDM_REPLACE, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDM_REPLACE, MF_GRAYED );

		//REPLACE USING TABLE
		//"Replace with table" is allowed if the file is not empty and read-only is disabled
		// and table is loaded and active
		if( FileBuffer.Length() > 0 && !bReadOnly && bTableLoaded && bTableActive)
			EnableMenuItem( (HMENU) w, IDM_TABLEREPLACE, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDM_TABLEREPLACE, MF_GRAYED );

		//SEARCH RELATIVE
		//"Search relative" is allowed if the file is not empty
		if( FileBuffer.Length() > 0 )
			EnableMenuItem( (HMENU) w, IDM_RELATIVEFIND, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDM_RELATIVEFIND, MF_GRAYED );

		//SCAN RELATIVE
		//"Scan relative" is allowed if the file is not empty
		if( FileBuffer.Length() > 0 )
			EnableMenuItem( (HMENU) w, IDM_RELATIVESCAN, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDM_RELATIVESCAN, MF_GRAYED );

		//VALUE SCAN RELATIVE
		//"Scan relative" is allowed if the file is not empty
		if( FileBuffer.Length() > 0 )
			EnableMenuItem( (HMENU) w, IDM_RELATIVESCANVAL, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDM_RELATIVESCANVAL, MF_GRAYED );

	}
	//BOOKMARKS
	else if( l == 5 )
	{
		//ADD BOOKMARK
		// "Add bookmark" is allowed if the file is not
		// empty and there is no selection going on.
		if( !bSelected && FileBuffer.Length() > 0 )
			EnableMenuItem( (HMENU) w, IDM_ADDBOOKMARK, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDM_ADDBOOKMARK, MF_GRAYED );

		//REMOVE BOOKMARK CLEAR BOOKMARK
		// "Remove bookmark" and "Clear all bookmarks" are allowed if there are bookmarks set.
		if( iBookmarkCount > 0 )
		{
			EnableMenuItem( (HMENU) w, IDM_REMOVE_BKM, MF_ENABLED );
			EnableMenuItem( (HMENU) w, IDM_CLEARALL_BMK, MF_ENABLED );
		}
		else
		{
			EnableMenuItem( (HMENU) w, IDM_REMOVE_BKM, MF_GRAYED );
			EnableMenuItem( (HMENU) w, IDM_CLEARALL_BMK, MF_GRAYED );
		}

		//BOOKMARKS
		// Create the bookmark list.
		make_bookmark_list( (HMENU) w );
	}
	//SCRIPT
	else if( l == 6)
	{
		//OPEN TABLE
		//"Open table" is always allowed
		EnableMenuItem( (HMENU) w, IDM_OPEN_TABLE, MF_ENABLED );

		//RECENT TABLES
		
			//RECENT TABLES
			make_most_recent_table_list( (HMENU) w );
		
		
		//CONVERT TABLE
		//"Convert table" is only allowed when a table is loaded and active
		if(bTableLoaded && bTableActive && !bReadOnly)
			EnableMenuItem( (HMENU) w, IDM_TABLE_CONVERT, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDM_TABLE_CONVERT, MF_GRAYED );
			
		//DUMP SCRIPT
		//"Dump Script" is allowed when a table is loaded and active and file is not empty
		if(bTableLoaded && bTableActive && FileBuffer.Length() > 0 )
			EnableMenuItem( (HMENU) w, IDM_SCRIPT_DUMP, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDM_SCRIPT_DUMP, MF_GRAYED );
		
		//REPLACE SCRIPT
		//"Replace Script" is allowed when table loaded and active and not read-only mode
		if(bTableLoaded && bTableActive && !bReadOnly)
			EnableMenuItem( (HMENU) w, IDM_REPLACE_SCRIPT, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDM_REPLACE_SCRIPT, MF_GRAYED );

		//OPTIMIZE SCRIPT
		//"Optimize Script" is allowed when table loaded and active
		if(bTableLoaded && bTableActive)
			EnableMenuItem( (HMENU) w, IDM_OPTIMIZESCRIPT, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDM_OPTIMIZESCRIPT, MF_GRAYED );

		//SCRIPTMARKS

			//SCRIPTMARKS
			make_scriptmark_list((HMENU) w);

		//FIND USING TABLE
		// "Find with table" is allowed if file is not empty & if table is loaded and active
		if( FileBuffer.Length() > 0 && bTableLoaded && bTableActive)
			EnableMenuItem( (HMENU) w, IDM_TABLEFIND, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDM_TABLEFIND, MF_GRAYED );
	
		//REPLACE USING TABLE
		//"Replace with table" is allowed if the file is not empty and read-only is disabled
		// and table is loaded and active
		if( FileBuffer.Length() > 0 && !bReadOnly && bTableLoaded && bTableActive)
			EnableMenuItem( (HMENU) w, IDM_TABLEREPLACE, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDM_TABLEREPLACE, MF_GRAYED );
	}
	//OPTIONS
	else if( l == 7)
	{
		//PREFERENCES
		EnableMenuItem( (HMENU) w, IDM_VIEW_SETTINGS, MF_ENABLED );
		
		//COLOR SETTINGS
		EnableMenuItem( (HMENU) w, IDM_COLOR_SETTINGS, MF_ENABLED );
		
		//BINARY MODE
		EnableMenuItem( (HMENU) w, IDM_BINARYMODE, MF_ENABLED );
		
		//EnableMenuItem( (HMENU) w, IDM_OFFSETMODE, MF_ENABLED );	
	}
	//SCROLL
	else if( l == 8)
	{
		//LEFT
		EnableMenuItem( (HMENU) w, IDM_SCROLL_LEFT, MF_ENABLED );
		
		//RIGHT
		EnableMenuItem( (HMENU) w, IDM_SCROLL_RIGHT, MF_ENABLED );
		
		//UP
		EnableMenuItem( (HMENU) w, IDM_SCROLL_UP, MF_ENABLED );
		
		//DOWN
		EnableMenuItem( (HMENU) w, IDM_SCROLL_DOWN, MF_ENABLED );
		
		//TOP
		EnableMenuItem( (HMENU) w, IDM_TOP, MF_ENABLED );
		
		//BOTTOM
		EnableMenuItem( (HMENU) w, IDM_BOTTOM, MF_ENABLED );

		//JUMP TO
		// "Go to" is allowed if the file isn't empty.
		if( FileBuffer.Length() > 0 )
			EnableMenuItem( (HMENU) w, IDM_GO_TO, MF_ENABLED );
		else
			EnableMenuItem( (HMENU) w, IDM_GO_TO, MF_GRAYED );

	}
	//HELP
	else if( l == 9)
	{
		//HELP
		EnableMenuItem( (HMENU) w, IDM_HELP_TOPICS, MF_ENABLED );
		
		//ABOUT
		EnableMenuItem( (HMENU) w, IDM_ABOUT, MF_ENABLED );

	}
	return 0;
}

int Translhextion::update_most_recent ()
{
	int i;
	for (i=0; i<iMostRecentCount; i++)
	{
		if (strMostRecent[i].Compare(filename)==0)  
		{
			GString temp=strMostRecent[0]; 
			
			for(int j=i; j>0; j--) strMostRecent[j]=strMostRecent[j-1];
			strMostRecent[0]=filename; 
			break;
		}
	}
	if (i==iMostRecentCount) 
	{
		if (iMostRecentCount<iMostRecentMaximum)
		{
			iMostRecentCount++;
			for (int j=iMostRecentCount-1; j>0; j--) strMostRecent[j]=strMostRecent[j-1];
			strMostRecent[0]=filename;
		}
		else
		{
			for (int j=iMostRecentMaximum-1; j>0; j--) strMostRecent[j]=strMostRecent[j-1];
			strMostRecent[0]=filename;
		}
	}
	save_ini_data ();
	return 1;
}

int Translhextion::make_most_recent_list (HMENU menu)
{
	while (RemoveMenu (GetSubMenu(menu,iMostRecentPos), 0, MF_BYPOSITION)==TRUE);
	
	if (iMostRecentCount>0)
	{
		GString cBuf;
		for (int i=0; i<iMostRecentCount; i++)
		{
			cBuf.Format(_T("&%d %s"), i+1, (LPCTSTR)strMostRecent[i]);
			HMENU m=GetSubMenu(menu,iMostRecentPos);
			AppendMenu(m, MF_ENABLED | MF_STRING, IDM_MRU1+i, cBuf);
		}
	}
	return 1;
}

int Translhextion::most_recent_selection (int cmd)
{
	if (cmd-IDM_MRU1+1>iMostRecentCount)
		return 0;

	if (file_can_load (strMostRecent[cmd-IDM_MRU1]))
	{
		if (iFileChanged == TRUE)
		{
			if( MessageBox (LoadString(IDS_NOTICE_DISCARD_CHANGES), LoadString(IDS_TITLE_NOTICE), MB_YESNO | MB_ICONQUESTION) == IDNO )
				return 0;
		}
		if (load_file (strMostRecent[cmd-IDM_MRU1]))
		{
			iVerticalScrollMax = 0;
			iVerticalScrollPos = 0;
			iVerticalScrollInc = 0;
			iHorizontalScrollMax = 0;
			iHorizontalScrollPos = 0;
			iHorizontalScrollInc = 0;
			iCurrentLine = 0;
			iCurrentByte = 0;
			iCurrentNibble = 0;
			iFileSize = FileBuffer.Length();
			iFileChanged = FALSE;
			bFilestatusChanged = TRUE;
			bFileNeverSaved = FALSE;
			bSelected = FALSE;
			update_most_recent ();
			update_size_change ();
		}
	}
	else
	{
		MessageBox (LoadString(IDS_NOTICE_FILE_CANT_ACCESS), LoadString(IDS_TITLE_NOTICE), MB_OK | MB_ICONINFORMATION);
		for(int j=cmd-IDM_MRU1; j<iMostRecentCount-1; j++) strMostRecent[j]=strMostRecent[j+1];
		iMostRecentCount--;
		save_ini_data ();
	}
	return 1;
}

int Translhextion::update_most_recent_table()
{
	int i;
	for (i=0; i<iMostRecentTableCount; i++)
	{
		if (strMostRecentTable[i].Compare(filename2)==0)  
		{
			GString temp=strMostRecentTable[0]; 
			for(int j=i; j>0; j--) strMostRecentTable[j]=strMostRecentTable[j-1];
			strMostRecentTable[0]=filename2; 
			break;
		}
	}
	if (i==iMostRecentTableCount) 
	{
		if (iMostRecentTableCount<iMostRecentTableMaximum)
		{
			iMostRecentTableCount++;
			for (int j=iMostRecentTableCount-1; j>0; j--) strMostRecentTable[j]=strMostRecentTable[j-1];
			strMostRecentTable[0]=filename2;
		}
		else
		{
			for (int j=iMostRecentTableMaximum-1; j>0; j--) strMostRecentTable[j]=strMostRecentTable[j-1];
			strMostRecentTable[0]=filename2;
		}
	}
	save_ini_data ();
	return 1;
}

int Translhextion::make_most_recent_table_list (HMENU menu)
{
	int i;
	while (RemoveMenu (GetSubMenu(menu,iMostRecentTablePos), 0, MF_BYPOSITION)==TRUE);
	
	if (iMostRecentTableCount>0)
	{
		//AppendMenu (menu, MF_SEPARATOR, 0, 0);
		GString cBuf;
		for (i=0; i<iMostRecentTableCount; i++)
		{
			cBuf.Format(_T("&%d %s"), i+1, (LPCTSTR)strMostRecentTable[i]);
			AppendMenu (GetSubMenu(menu,iMostRecentTablePos), MF_ENABLED | MF_STRING, IDM_MRTABLE1+i, cBuf);
		}
	}
	return 1;
}

int Translhextion::most_recent_table_selection (int cmd)
{
	if (cmd-IDM_MRTABLE1+1>iMostRecentTableCount)
		return 0;

	if (file_can_load (strMostRecentTable[cmd-IDM_MRTABLE1]))
	{
		if (bTableLoaded)
		{
			if (MessageBox (LoadString(IDS_NOTICE_TABLE_DISCARD), LoadString(IDS_TITLE_NOTICE), MB_YESNO | MB_ICONQUESTION) == IDNO)
				return 0;
		}
		_tcscpy(filename2,strMostRecentTable[cmd-IDM_MRTABLE1].GetBuffer());

		if(wread_table_file(filename2))
		{			
			if(iRealTable > 0)
			{
				if(bTableLoaded)
				{
					bTableActive = false;
					bThingyView = false;
					CheckDlgButton(hwndTBar,IDC_CHECK1,BST_UNCHECKED);
					CheckDlgButton(hwndTBar,IDC_CHECK2,BST_UNCHECKED);
					if(bJPuncSwitch)
					{
						CheckDlgButton(hwndTBar,IDC_CHECK4, BST_UNCHECKED);
					}
					if(bDumpClean)
					{
						CheckDlgButton(hwndTBar,IDC_CHECK3, BST_CHECKED);
					}
					bTableLoaded = true;
					bTableActive = true;
					sLoadedTable = filename2;
				}
				else
				{
					bTableLoaded = true;
					bTableActive = true;
					hwndTBar = CreateDialog(hInstance, MAKEINTRESOURCE (IDD_THINGYBAR),*this,ToolBarDialogProc);
					sLoadedTable = filename2;
				}
				//when using optimizations under >= vc 6.0 then crash issues start here
				// possibly memory is corrupted at some point before this?
				// or maybe STL cannot handle optimizations?
				GString message;
				message.Format(LoadString(IDS_NOTICE_TBL_TOKEN_CNT),iRealTable);
				MessageBox(message,LoadString(IDS_TITLE_NOTICE), MB_OK | MB_ICONINFORMATION);
			}
			else
			{
				if(bTableLoaded)
				{
					DestroyWindow(hwndTBar);
					bTableLoaded = false;
					bTableActive = false;
					bThingyView = false;
					//vTableFileLeft = vEmpty;
					//vTableFileRight = vEmpty;
					sLoadedTable = _T("");
				}
				MessageBox(LoadString(IDS_TBLERR_UNKNOWN_FORMAT),LoadString(IDS_TITLE_TABLE_ERROR), MB_OK | MB_ICONERROR);
			}
		}
		else
		{
			//fs.close();
			MessageBox(LoadString(IDS_TBLERR_READ_ERROR),LoadString(IDS_TITLE_TABLE_ERROR),MB_OK | MB_ICONERROR);
		}
	}
	else
	{
		MessageBox (LoadString(IDS_NOTICE_FILE_CANT_ACCESS), LoadString(IDS_TITLE_NOTICE), MB_OK | MB_ICONINFORMATION);
		for (int j=cmd-IDM_MRTABLE1; j<iMostRecentTableCount-1; j++) strMostRecentTable[j]=strMostRecentTable[j+1];
		iMostRecentTableCount--;
		save_ini_data ();
	}
	return 1;
}

int Translhextion::make_scriptmark_list (HMENU menu)
{
	int i;
	int sm1place = IDM_SCRIPTMARK1;
	while (RemoveMenu (GetSubMenu(menu,SMPOS), 0, MF_BYPOSITION)==TRUE)
		;

	if (vScriptDumps.size()>0)
	{
		_tstring temp;
		int j = 0;
		for (i=0; i<(int)vScriptDumps.size(); i++)
		{
			if (vScriptDumps[i].name == L"")
			{
				temp = L"[" + stringvalue(vScriptDumps[i].start) + L"-" + stringvalue(vScriptDumps[i].end) + L"]";
			}
			else
			{
				temp = vScriptDumps[i].name + L"[" + stringvalue(vScriptDumps[i].start) + L"-" + stringvalue(vScriptDumps[i].end) + L"]";
			}
			if (bTableLoaded && bTableActive && vScriptDumps[i].end <= FileBuffer.Length())
				AppendMenu (GetSubMenu(menu,SMPOS), MF_ENABLED | MF_STRING, IDM_SCRIPTMARK1+i, temp.c_str());
			else
				AppendMenu (GetSubMenu(menu,SMPOS), MF_GRAYED | MF_STRING, IDM_SCRIPTMARK1+i, temp.c_str());
		}
	}
	return 1;
}

int Translhextion::make_bookmark_list (HMENU menu)
{
	int i;
	while (RemoveMenu (menu, iBookmarkPos, MF_BYPOSITION)==TRUE)
		;

	if (iBookmarkCount>0)
	{
		AppendMenu (menu, MF_SEPARATOR, 0, 0);
		GString cBuf;
		long bookmark = 0;
		for (i=0; i<iBookmarkCount; i++)
		{
			bookmark = pbmkList[i].offset;
			if (pbmkList[i].name == NULL)
				cBuf.Format(_T("&%d 0x%X"), i+1, bookmark);
			else
				cBuf.Format(_T("&%d 0x%X:%s"), i+1, bookmark, pbmkList[i].name);
			if(iOffsetMode == LOROM)
				bookmark = fromLOROM(bookmark);
			else if(iOffsetMode == HIROM)
				bookmark = fromHIROM(bookmark);
			if (bookmark <= FileBuffer.Length() && !bSelected)
				AppendMenu (menu, MF_ENABLED | MF_STRING, IDM_BOOKMARK1+i, cBuf);
			else
				AppendMenu (menu, MF_GRAYED | MF_STRING, IDM_BOOKMARK1+i, cBuf);
		}
	}
	return 1;
}

//FILE
int Translhextion::_New ()
{
	if (iFileChanged == TRUE)
	{
		if( MessageBox (LoadString(IDS_NOTICE_DISCARD_NEW), LoadString(IDS_TITLE_NOTICE), MB_YESNO | MB_ICONQUESTION) == IDNO )
			return 0;
	}
	bFileNeverSaved = TRUE;
	bSelected = FALSE;
	bLButtonIsDown = FALSE;
	iFileChanged = FALSE;
	bFilestatusChanged = TRUE;
	iVerticalScrollMax = 0;
	iVerticalScrollPos = 0;
	iVerticalScrollInc = 0;
	iHorizontalScrollMax = 0;
	iHorizontalScrollPos = 0;
	iHorizontalScrollInc = 0;
	iCurrentLine = 0;
	iCurrentByte = 0;
	iCurrentNibble = 0;
	iFileSize = 0;
	bPartialOpen=FALSE;
	FileBuffer.Reset ();
	vChanges = vEmpty;
	vHighlights = vEmpty;
	vDTEs = vEmpty;
	filename=_T("Untitled");
	update_size_change ();
	repaint ();
	return 1;
}

int Translhextion::close ()
{
	if( iFileChanged == TRUE )
	{
		if( MessageBox (LoadString(IDS_NOTICE_DISCARD_EXIT), LoadString(IDS_TITLE_NOTICE), MB_YESNO | MB_ICONQUESTION) == IDNO )
			return 0;
	}
	else
	{
		TCHAR path[500];
#ifdef UNICODE
		_tcscpy(path,_wpgmptr);
#else
		strcpy (path, _pgmptr);
#endif
		int len = strlen (path);
		path[len-3] = 'h';
		path[len-2] = 'l';
		path[len-1] = 'p';
		WinHelp (*this, path, HELP_QUIT, 0);
	}

	WINDOWPLACEMENT wndpl;
	wndpl.length = sizeof( WINDOWPLACEMENT );
	GetWindowPlacement( *this, &wndpl );
	iWindowShowCmd = wndpl.showCmd;
	iWindowX = wndpl.rcNormalPosition.left;
	iWindowY = wndpl.rcNormalPosition.top;
	iWindowWidth = wndpl.rcNormalPosition.right - iWindowX;
	iWindowHeight = wndpl.rcNormalPosition.bottom - iWindowY;
	save_ini_data();

	if(bTableLoaded)
	{
		DestroyWindow(hwndTBar);
	}
		DestroyWindow( *this );
	return 0;
}


int Translhextion::open ()
{
	if (iFileChanged == TRUE)
	{
		if( MessageBox (LoadString(IDS_NOTICE_DISCARD_CHANGES), LoadString(IDS_TITLE_NOTICE), MB_YESNO | MB_ICONQUESTION) == IDNO )
			return 0;
	}

	CFileDialog dlg;
	dlg.Create(*this,LoadString(IDS_FILTER_ALL),_T(""),OFN_HIDEREADONLY | OFN_CREATEPROMPT);

	if (dlg.DoModal())
	{
		if (load_file (dlg.GetFileName()/*cFileName*/))
		{
			iVerticalScrollMax = 0;
			iVerticalScrollPos = 0;
			iVerticalScrollInc = 0;
			iHorizontalScrollMax = 0;
			iHorizontalScrollPos = 0;
			iHorizontalScrollInc = 0;
			iCurrentLine = 0;
			iCurrentByte = 0;
			iCurrentNibble = 0;
			bSelected = FALSE;
			iFileChanged = FALSE;
			bFilestatusChanged = TRUE;
			bFileNeverSaved = FALSE;
			iFileSize = FileBuffer.Length();
			RECT r;
			GetClientRect (*this, &r);
			SendMessage (*this, WM_SIZE, 0, (r.bottom << 16) | r.right);
			InvalidateRect (*this, NULL, FALSE);
			UpdateWindow (*this);
		}					
	}
	return 1;
}


int Translhextion::open_partially ()
{
	if (iFileChanged == TRUE)
	{
		if( MessageBox (LoadString(IDS_NOTICE_DISCARD_CHANGES), LoadString(IDS_TITLE_NOTICE), MB_YESNO | MB_ICONQUESTION) == IDNO )
			return 0;
	}
	CFileDialog dlg;
	dlg.Create(*this,LoadString(IDS_FILTER_ALL),_T(""),OFN_HIDEREADONLY | OFN_CREATEPROMPT | OFN_FILEMUSTEXIST);

	if (dlg.DoModal())
	{
		int iFileHandle, iFileLength;
		if ((iFileHandle = _topen (dlg.GetFileName()/*cFileName*/,_O_RDONLY|_O_BINARY,_S_IREAD|_S_IWRITE)) != -1)
		{
			iFileLength = _filelength (iFileHandle);
			_close (iFileHandle);
		}
		iStartPL = 0;
		iNumBytesPl = iFileLength;
		iPLFileLength = iFileLength;
		if (DialogBox (hInstance, MAKEINTRESOURCE (IDD_OPEN_PARTIAL_DIALOG), *this, (DLGPROC) OpenPartiallyDialogProc))
		{
			if (iStartPL+iNumBytesPl<=iFileLength)
			{
				if ((iFileHandle = _topen (dlg.GetFileName(),_O_RDONLY|_O_BINARY,_S_IREAD|_S_IWRITE)) != -1)
				{
					FileBuffer.Reset ();
					vChanges = vEmpty;
					vHighlights = vEmpty;
					vDTEs = vEmpty;
					if (FileBuffer.SetLength (iNumBytesPl) == TRUE)
					{
						std::vector<_tstring> temp(iNumBytesPl);
						vChanges = temp;
						vHighlights = temp;
						vDTEs = temp;
						//int m = 0;
						//for(m = 0;m<vChanges.size();m++)
						//	vChanges[m] = COLORNORMAL;
						FileBuffer.SetUpperBound (iNumBytesPl-1);
						_lseek (iFileHandle, iStartPL, 0);
						iPartialOffset = iStartPL;
						if (_read (iFileHandle, FileBuffer, iNumBytesPl) != -1)
						{
							_close (iFileHandle);
							iFileSize = FileBuffer.Length();
							if( bOpenReadOnly )
								bReadOnly = TRUE;
							else
								bReadOnly = FALSE;
							filename=dlg.GetFileName();
							bFileNeverSaved = FALSE;
							iVerticalScrollMax = 0;
							iVerticalScrollPos = 0;
							iVerticalScrollInc = 0;
							iHorizontalScrollMax = 0;
							iHorizontalScrollPos = 0;
							iHorizontalScrollInc = 0;
							iCurrentLine = 0;
							iCurrentByte = 0;
							iCurrentNibble = 0;
							iFileChanged = FALSE;
							bFilestatusChanged = TRUE;
							bFileNeverSaved = FALSE;
							bPartialOpen=TRUE;
							RECT r;
							GetClientRect (*this, &r);
							SendMessage (*this, WM_SIZE, 0, (r.bottom << 16) | r.right);
							InvalidateRect (*this, NULL, FALSE);
							UpdateWindow (*this);
							return TRUE;
						}
						else
						{
							_close (iFileHandle);
							MessageBoxA (*this, "Error occurred while reading from file.", "Partial open error:", MB_OK | MB_ICONERROR);
							return FALSE;
						}
					}
					else
					{
						MessageBoxA (*this, "Not enough memory to load file.", "Partial open error:", MB_OK | MB_ICONERROR);
						return FALSE;
					}
				}
				else
				{
					GString cBuf;
					cBuf.Format(_T("Error code 0x%X occured while opening file %s."), errno, (LPCTSTR)dlg.GetFileName());
					MessageBox (cBuf, _T("Partial open error:"), MB_OK | MB_ICONERROR);
					return FALSE;
				}
			}
			else
			{
				MessageBoxA (*this, "More bytes were specified than there are in the file.", "Partial open error:", MB_OK | MB_ICONERROR);
				return 0;
			}
		}
	}
	return 1;
}

void Translhextion::revert()
{
	if (load_file (filename))
	{
		iVerticalScrollMax = iVerticalScrollPos = iVerticalScrollInc = iHorizontalScrollMax = iHorizontalScrollPos = 
		iHorizontalScrollInc = iCurrentLine = iCurrentByte = iCurrentNibble = 0;
		iFileSize = FileBuffer.Length();
		iFileChanged = FALSE;
		bFilestatusChanged = TRUE;
		bFileNeverSaved = FALSE;
		bSelected=FALSE;
		RECT r;
		GetClientRect (*this, &r);
		SendMessage (*this, WM_SIZE, 0, (r.bottom << 16) | r.right);
		InvalidateRect (*this, NULL, FALSE);
		UpdateWindow (*this);
	}					
}

int Translhextion::save ()
{
	int choice = IDYES;
	if (bPartialOpen)
	{
		if(iFileSize != FileBuffer.Length())
		{
			long diff = FileBuffer.Length() - iFileSize;
			_tstring change;
			if(diff > 0)
			{
				change = L"+" + stringvalue(diff);
			}
			else
			{
				change = stringvalue(diff);
			}
			GString message;
			message.Format(LoadString(IDS_NOTICE_FILE_CHANGE_SIZE),change.c_str());
			choice = MessageBox(message,LoadString(IDS_TITLE_NOTICE), MB_YESNO | MB_ICONINFORMATION);
		}
		if(choice == IDYES)
		{
			int iFileHandle;
			if ((iFileHandle = _topen (filename,_O_RDWR|_O_BINARY,_S_IREAD|_S_IWRITE)) != -1)
			{
				WaitCursor w1;
				if( _lseek( iFileHandle, iPartialOffset, 0 ) == -1 )
				{
					MessageBoxA( *this, "Could not seek to proper location in file.", "Partial save error:", MB_OK | MB_ICONERROR );
					_close( iFileHandle );
					return 0;
				}
				if( _write( iFileHandle, FileBuffer, FileBuffer.Length() ) == -1 )
				{
					MessageBoxA( *this, "Could not write data to file.", "Partial save error:", MB_OK | MB_ICONERROR );
				}
				_close (iFileHandle);
				iFileChanged = FALSE;
				bFilestatusChanged = TRUE;
				if(bDiscardChangesSave)
				{
					std::vector<_tstring> empty(vHighlights.size());
					vChanges = empty;
					iFileSize = FileBuffer.Length();
					//long r = 0;
					//for(r = 0;r<vChanges.size();r++)
					//{
					//	if(vChanges[r] == COLORCHANGE)
					//	{
					//		vChanges[r] = COLORNORMAL;
					//	}
					//}
				}
			}
			else
			{
				MessageBoxA (*this, "Could not save partially opened file.", "Partial save error:", MB_OK | MB_ICONERROR );
			}
			repaint ();
		}
		return 1;
	}
	if( bFileNeverSaved )
	{
		MessageBox (LoadString(IDS_NOTICE_FILE_UNTITLED), LoadString(IDS_TITLE_NOTICE), MB_OK | MB_ICONINFORMATION);
		return 0;
	}
	if(iFileSize != FileBuffer.Length())
	{
		long diff = FileBuffer.Length() - iFileSize;
		_tstring change;
		if(diff > 0)
		{
			change = L"+" + stringvalue(diff);
		}
		else
		{
			change = stringvalue(diff);
		}
		GString message;
		message.Format(LoadString(IDS_NOTICE_FILE_CHANGE_SIZE),change.c_str());
		choice = MessageBox(message,LoadString(IDS_TITLE_NOTICE), MB_YESNO | MB_ICONINFORMATION);
	}
	if(choice == IDYES)
	{
		int iFileHandle;
		if ((iFileHandle = _topen (filename,_O_RDWR|_O_CREAT|_O_TRUNC|_O_BINARY,_S_IREAD|_S_IWRITE)) != -1)
		{
			SetCursor (LoadCursor (NULL, IDC_WAIT));
			_write (iFileHandle, FileBuffer, FileBuffer.Length ());
			_close (iFileHandle);
			if(bDiscardChangesSave)
			{
				std::vector<_tstring> empty(vHighlights.size());
				vChanges = empty;
				iFileSize = FileBuffer.Length();
				//long r = 0;
				//for(r = 0;r<vChanges.size();r++)
				//{
				//	if(vChanges[r] == COLORCHANGE)
				//	{
				//		vChanges[r] = COLORNORMAL;
				//	}
				//}
			}
			SetCursor (LoadCursor (NULL, IDC_ARROW));
			iFileChanged = FALSE;
			bFilestatusChanged = TRUE;
			bPartialOpen=FALSE;
		}
		else
		{
			MessageBoxA (*this, "Could not save file.", "Save error:", MB_OK | MB_ICONERROR);
		}
		repaint ();
	}
	return 1;
}

int Translhextion::save_as ()
{
	CFileDialog dlg;
	dlg.Create(*this,LoadString(IDS_FILTER_ALL),_T(""),OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,false);

	if (dlg.DoModal())
	{
		int iFileHandle;
		if ((iFileHandle = _topen (dlg.GetFileName()/*cFileName*/, _O_RDWR|_O_CREAT|_O_TRUNC|_O_BINARY,_S_IREAD|_S_IWRITE)) != -1)
		{
			SetCursor (LoadCursor (NULL, IDC_WAIT));
			if ((_write (iFileHandle, FileBuffer, FileBuffer.Length ())) != -1)
			{
				//strcpy (filename, cFileName);
				iFileChanged = FALSE;
				bFilestatusChanged = TRUE;
				bFileNeverSaved = FALSE;
				bPartialOpen=FALSE;
				if(bDiscardChangesSave)
				{
					std::vector<_tstring> empty(vHighlights.size());
					vChanges = empty;
					//long r = 0;
					//for(r = 0;r<vChanges.size();r++)
					//{
					//	if(vChanges[r] == COLORCHANGE)
					//	{
					//		vChanges[r] = COLORNORMAL;
					//	}
					//}
				}
				update_most_recent();
			}
			else
				MessageBoxA (*this, "Could not save file.", "Save as error:", MB_OK | MB_ICONERROR);
			SetCursor (LoadCursor (NULL, IDC_ARROW));
			_close (iFileHandle);
		}
		else
			MessageBoxA (*this, "Could not save file.", "Save as error:", MB_OK | MB_ICONERROR);
	}
	repaint ();
	return 1;
}

void Translhextion::deletefile()
{
	if(IDYES==MessageBox(LoadString(IDS_NOTICE_FILE_DELETE),LoadString(IDS_TITLE_NOTICE),MB_ICONQUESTION |MB_YESNO))
	{
		if(IDYES==MessageBox(LoadString(IDS_NOTICE_FILE_DELETE_2),LoadString(IDS_TITLE_NOTICE),MB_ICONQUESTION|MB_YESNO))
		{
			if(DeleteFile(filename))
			{
				iFileChanged = FALSE;
				_New();
			}
			else MessageBoxA (*this, "Could not delete file.", "Delete file error:", MB_OK | MB_ICONERROR);
		}
	}
}

int Translhextion::properties ()
{
	TCHAR cBuf[1000], buf2[500], *pc;
	sprintf (cBuf, _T("File name and path: "));
	GetFullPathName (filename, 500, buf2, &pc);
	strcat (cBuf, buf2);
	if( bPartialOpen )
	{
		if(iOffsetMode == LOROM)
			sprintf (buf2, _T("\nPartially opened at offset 0x%X = %d.\n")
			_T("Number of bytes read: %d = %d kilobytes.\n"),
			iPartialOffset, toLOROM(iPartialOffset), FileBuffer.Length(), FileBuffer.Length()/1024);
		else if(iOffsetMode == HIROM)
			sprintf (buf2, _T("\nPartially opened at offset 0x%X = %d.\n")
			_T("Number of bytes read: %d = %d kilobytes.\n"),
			iPartialOffset, toHIROM(iPartialOffset), FileBuffer.Length(), FileBuffer.Length()/1024);
		else
			sprintf (buf2, _T("\nPartially opened at offset 0x%X = %d.\n")
			_T("Number of bytes read: %d = %d kilobytes.\n"),
			iPartialOffset, iPartialOffset, FileBuffer.Length(), FileBuffer.Length()/1024);
		strcat (cBuf, buf2);
	}
	else
	{
		sprintf (buf2, _T("\nFile size: %d bytes = %d kilobytes.\n"), FileBuffer.Length(), FileBuffer.Length()/1024);
		strcat (cBuf, buf2);
	}
	sprintf (buf2, _T("\nNumber of hexdump lines: %d.\n"), iNumlines);
	strcat (cBuf, buf2);
	MessageCopyBox (NULL, cBuf, _T("File properties"), MB_ICONINFORMATION, *this);
	return 1;
}

int Translhextion::apply_template()
{
	if( FileBuffer.Length() == 0 )
	{
		MessageBoxA( *this, "File is empty.", "Template error:", MB_OK | MB_ICONERROR );
		return FALSE;
	}

	CFileDialog dlg;
	dlg.Create(NULL,LoadString(IDS_FILTER_TEMPLATE),LoadString(IDS_FILTER_TEMPLATE_TITLE),OFN_HIDEREADONLY | OFN_CREATEPROMPT | OFN_FILEMUSTEXIST);

	if(dlg.DoModal()/* GetOpenFileName( &ofn ) */)
	{
		apply_template( dlg.GetFileName()/*szTemplateName*/ );
	}
	return TRUE;
}

int Translhextion::apply_template(LPCTSTR pcTemplate )
{
	//int iFileHandle;
	//if( ( iFileHandle = _topen( pcTemplate, _O_RDONLY|_O_BINARY, _S_IREAD|_S_IWRITE ) ) != -1 )
	//{
	//	int tpl_filelen = _filelength( iFileHandle );
	//	if( tpl_filelen > 0 )
	//	{
	//		char* pcTpl = new char[ tpl_filelen ];
	//		if( pcTpl != NULL && _read( iFileHandle, pcTpl, tpl_filelen ) != -1 )
	//		{
	//			FileVector<char> TplResult;
	//			TplResult.SetLength( 1, 100 );
	//			TplResult.AppendArray( "File: ", 6 );
	//			TplResult.AppendArray( (char*)filename, strlen( filename ) );
	//			TplResult.AppendArray( "\xd\xa", 2 );
	//			TplResult.AppendArray( "Template file: ", 15 );
	//			TplResult.AppendArray( (char*)pcTemplate, strlen( pcTemplate ) );
	//			TplResult.AppendArray( "\xd\xa", 2 );
	//			TplResult.AppendArray( "Applied at offset: ", 19 );
	//			char cBuf[16];
	//			sprintf( cBuf, "%d\xd\xa\xd\xa", iCurrentByte );
	//			TplResult.AppendArray( cBuf, strlen( cBuf ) );
	//			apply_template_on_memory( pcTpl, tpl_filelen, TplResult );
	//			TplResult.Append( '\0' );
	//			pcTmplText = TplResult;
	//			DialogBox( hInstance, MAKEINTRESOURCE( IDD_TMPL_RESULT_DIALOG ), *this, (DLGPROC) TmplDisplayDialogProc );
	//		}
	//		else
	//			MessageBoxA( *this, "Template file could not be loaded.", "Template load error:", MB_OK | MB_ICONERROR );
	//		if( pcTpl != NULL )
	//			delete [] pcTpl;
	//	}
	//	else
	//		MessageBoxA( *this, "Template file is empty.", "Template error:", MB_OK | MB_ICONERROR );
	//	_close( iFileHandle );
	//}
	//else
	//{
	//	char cBuf[500];
	//	sprintf( cBuf, "Error code 0x%X occured while\nopening template file %s.", errno, pcTemplate );
	//	MessageBox( *this, cBuf, "Template error:", MB_OK | MB_ICONERROR );
	//	return FALSE;
	//}
	return TRUE;
}

int Translhextion::apply_template_on_memory( char* pcTpl, int tpl_len, FileVector<char>& ResultArray )
{
	//int index = 0, fpos = iCurrentByte;
	//while( index < tpl_len )
	//{
	//	if( ignore_non_code( pcTpl, tpl_len, index ) == TRUE )
	//	{
	//		char cmd[ TPL_TYPE_MAXLEN ]; 
	//		if( read_tpl_token( pcTpl, tpl_len, index, cmd ) == TRUE )
	//		{
	//			if( strcmp( cmd, "BYTE" ) == 0 || strcmp( cmd, "char" ) == 0 )
	//			{
	//				if( ignore_non_code( pcTpl, tpl_len, index ) == TRUE )
	//				{
	//					if( FileBuffer.Length() - fpos >= 1 )
	//					{
	//						char name[ TPL_NAME_MAXLEN ];
	//						read_tpl_token( pcTpl, tpl_len, index, name );
	//						ResultArray.AppendArray( cmd, strlen(cmd) );
	//						ResultArray.Append( ' ' );
	//						ResultArray.AppendArray( name, strlen(name) );
	//						
	//						char cBuf[ TPL_NAME_MAXLEN + 200];
	//						if( FileBuffer[fpos] != 0 )
	//							sprintf( cBuf, " = %d (signed) = %u (unsigned) = 0x%X = \'%c\'\xd\xa", (int) (signed char) FileBuffer[fpos], FileBuffer[fpos], FileBuffer[fpos], FileBuffer[fpos] );
	//						else
	//							sprintf( cBuf, " = %d (signed) = %u (unsigned) = 0x%X\xd\xa", (int) (signed char) FileBuffer[fpos], FileBuffer[fpos], FileBuffer[fpos] );
	//						ResultArray.AppendArray( cBuf, strlen(cBuf) );
	//						
	//						fpos += 1;
	//					}
	//					else
	//					{
	//						ResultArray.AppendArray( "ERROR: not enough space for byte-size datum.", 45 );
	//						return FALSE;
	//					}
	//				}
	//				else
	//				{
	//					
	//					ResultArray.AppendArray( "ERROR: missing variable name.", 29 );
	//					return FALSE;
	//				}
	//			}
	//			else if( strcmp( cmd, "WORD" ) == 0 || strcmp( cmd, "short" ) == 0 )
	//			{
	//				
	//				if( ignore_non_code( pcTpl, tpl_len, index ) == TRUE )
	//				{
	//					
	//					if( FileBuffer.Length() - fpos >= 2 )
	//					{
	//						
	//						char name[ TPL_NAME_MAXLEN ];
	//						read_tpl_token( pcTpl, tpl_len, index, name );
	//						
	//						ResultArray.AppendArray( cmd, strlen(cmd) );
	//						ResultArray.Append( ' ' );
	//						
	//						ResultArray.AppendArray( name, strlen(name) );
	//						WORD wd;
	//						if( iBinaryMode == LITTLE_ENDIAN )
	//						{
	//							wd = *( (WORD*)( &FileBuffer[ fpos ] ) );
	//						}
	//						else 
	//						{
	//							int i;
	//							for( i=0; i<2; i++ )
	//								((char*)&wd)[ i ] = FileBuffer[ fpos + 1 - i ];
	//						}
	//						char cBuf[ TPL_NAME_MAXLEN + 200 ];
	//						sprintf( cBuf, " = %d (signed) = %u (unsigned) = 0x%X\xd\xa", (int) (signed short) wd, wd, wd );
	//						ResultArray.AppendArray( cBuf, strlen(cBuf) );
	//						fpos += 2;
	//					}
	//					else
	//					{
	//						ResultArray.AppendArray( "ERROR: not enough space for WORD.", 34 );
	//						return FALSE;
	//					}
	//				}
	//				else
	//				{
	//					ResultArray.AppendArray( "ERROR: missing variable name.", 29 );
	//					return FALSE; 
	//				}
	//			}
	//			else if( strcmp( cmd, "DWORD" ) == 0 || strcmp( cmd, "int" ) == 0 ||
	//				strcmp( cmd, "long" ) == 0 || strcmp( cmd, "LONG" ) == 0 )
	//			{
	//				
	//				if( ignore_non_code( pcTpl, tpl_len, index ) == TRUE )
	//				{
	//					
	//					if( FileBuffer.Length() - fpos >= 4 )
	//					{
	//						
	//						char name[ TPL_NAME_MAXLEN ];
	//						read_tpl_token( pcTpl, tpl_len, index, name );
	//						
	//						ResultArray.AppendArray( cmd, strlen(cmd) );
	//						ResultArray.Append( ' ' );
	//						
	//						ResultArray.AppendArray( name, strlen(name) );
	//						DWORD dw;
	//						
	//						if( iBinaryMode == LITTLE_ENDIAN )
	//						{
	//							dw = *( (DWORD*)( &FileBuffer[ fpos ] ) );
	//						}
	//						else 
	//						{
	//							int i;
	//							for( i=0; i<4; i++ )
	//								((char*)&dw)[ i ] = FileBuffer[ fpos + 3 - i ];
	//						}
	//						char cBuf[ TPL_NAME_MAXLEN + 200 ];
	//						sprintf( cBuf, " = %d (signed) = %u (unsigned) = 0x%X\xd\xa", (signed long) dw, (unsigned long) dw, dw );
	//						ResultArray.AppendArray( cBuf, strlen(cBuf) );
	//						fpos += 4;
	//					}
	//					else
	//					{
	//						ResultArray.AppendArray( "ERROR: not enough space for DWORD.", 34 );
	//						return FALSE;
	//					}
	//				}
	//				else
	//				{
	//					ResultArray.AppendArray( "ERROR: missing variable name.", 29 );
	//					return FALSE; 
	//				}
	//			}
	//			else if( strcmp( cmd, "float" ) == 0 )
	//			{
	//				
	//				if( ignore_non_code( pcTpl, tpl_len, index ) == TRUE )
	//				{
	//					
	//					if( FileBuffer.Length() - fpos >= 4 )
	//					{
	//						
	//						char name[ TPL_NAME_MAXLEN ];
	//						read_tpl_token( pcTpl, tpl_len, index, name );
	//						
	//						ResultArray.AppendArray( cmd, strlen(cmd) );
	//						ResultArray.Append( ' ' );
	//						
	//						ResultArray.AppendArray( name, strlen(name) );
	//						float f;
	//						
	//						if( iBinaryMode == LITTLE_ENDIAN )
	//						{
	//							f = *( (float*)( &FileBuffer[ fpos ] ) );
	//						}
	//						else 
	//						{
	//							int i;
	//							for( i=0; i<4; i++ )
	//								((char*)&f)[ i ] = FileBuffer[ fpos + 3 - i ];
	//						}
	//						char cBuf[ TPL_NAME_MAXLEN + 200 ];
	//						sprintf( cBuf, " = %f = 0x%X\xd\xa", f, (unsigned long) *((int*) &f) );
	//						ResultArray.AppendArray( cBuf, strlen(cBuf) );
	//						fpos += 4;
	//					}
	//					else
	//					{
	//						ResultArray.AppendArray( "ERROR: not enough space for float.", 34 );
	//						return FALSE;
	//					}
	//				}
	//				else
	//				{
	//					ResultArray.AppendArray( "ERROR: missing variable name.", 29 );
	//					return FALSE; 
	//				}
	//			}
	//			else if( strcmp( cmd, "double" ) == 0 )
	//			{
	//				
	//				if( ignore_non_code( pcTpl, tpl_len, index ) == TRUE )
	//				{
	//					
	//					if( FileBuffer.Length() - fpos >= 8 )
	//					{
	//						
	//						char name[ TPL_NAME_MAXLEN ];
	//						read_tpl_token( pcTpl, tpl_len, index, name );
	//						
	//						ResultArray.AppendArray( cmd, strlen(cmd) );
	//						ResultArray.Append( ' ' );
	//						
	//						ResultArray.AppendArray( name, strlen(name) );
	//						double d;
	//						
	//						if( iBinaryMode == LITTLE_ENDIAN )
	//						{
	//							d = *( (double*)( &FileBuffer[ fpos ] ) );
	//						}
	//						else 
	//						{
	//							int i;
	//							for( i=0; i<8; i++ )
	//								((char*)&d)[ i ] = FileBuffer[ fpos + 7 - i ];
	//						}
	//						char cBuf[ TPL_NAME_MAXLEN + 200 ];
	//						sprintf( cBuf, " = %g\xd\xa", d );
	//						ResultArray.AppendArray( cBuf, strlen(cBuf) );
	//						fpos += 8;
	//					}
	//					else
	//					{
	//						ResultArray.AppendArray( "ERROR: not enough space for double.", 35 );
	//						return FALSE;
	//					}
	//				}
	//				else
	//				{
	//					ResultArray.AppendArray( "ERROR: missing variable name.", 29 );
	//					return FALSE; 
	//				}
	//			}
	//			else
	//			{
	//				ResultArray.AppendArray( "ERROR: Unknown variable type \"", 30 );
	//				ResultArray.AppendArray( cmd, strlen( cmd ) );
	//				ResultArray.Append( '\"' );
	//				return FALSE;
	//			}
	//		}
	//		else
	//		{
	//			
	//			ResultArray.AppendArray( "ERROR: Missing variable name.", 29 );
	//			return FALSE;
	//		}
	//	}
	//	else
	//	{
	//		
	//		break;
	//	}
	//}
	//
	//char cBuf[128];
	//sprintf( cBuf, "\xd\xa-> Lengthgth of template = %d bytes.\xd\xa", fpos - iCurrentByte );
	//ResultArray.AppendArray( cBuf, strlen( cBuf ) );
	return TRUE;
}

int Translhextion::ignore_non_code( char* pcTpl, int tpl_len, int& index )
{
	while( index < tpl_len )
	{
		
		switch( pcTpl[ index ] )
		{
		case ' ': case '\t': case 0x0d: case 0x0a:
			break;

		default:
			return TRUE;
		}
		index++;
	}
	return FALSE;
}

int Translhextion::read_tpl_token( char* pcTpl, int tpl_len, int& index, char* dest )
{
	int i = 0;
	while( index + i < tpl_len )
	{
		switch( pcTpl[ index + i ] )
		{
		case ' ': case '\t': case 0x0d: case 0x0a:
			dest[i] = '\0';
			index += i;
			return TRUE;

		default:
			dest[i] = pcTpl[ index + i ];
		}
		i++;
	}
	dest[i] = '\0';
	index += i;
	return FALSE;
}

int Translhextion::summon_text_edit()
{
	if(!filename.IsEmpty())
	{
		HINSTANCE hi = ShellExecute( *this, _T("open"), sTexteditorName.c_str(), filename, NULL, SW_SHOWNORMAL );
		if( (int) hi <= 32 )
			MessageBoxA( *this, "Error occured when opening text editor.", "Text editing error:", MB_OK | MB_ICONERROR );
	}
	else
	{
		MessageBoxA( *this, "Filename is NULL.", "Text editing error:", MB_OK | MB_ICONERROR );
	}
	return 0;
}

//SELECTION

int Translhextion::edit_cut ()
{
	if (bSelected) 
	{
		if (iEndOfSelection >= iStartOfSelection)
		{
			iCutOffset = iStartOfSelection;
			iCutNumberOfBytes = iEndOfSelection-iStartOfSelection+1;
		}
		else
		{
			iCutOffset = iEndOfSelection;
			iCutNumberOfBytes = iStartOfSelection-iEndOfSelection+1;
		}
	}
	else 
	{
		iCutOffset = iCurrentByte;
		iCutNumberOfBytes = 1;
	}
	if (DialogBox (hInstance, MAKEINTRESOURCE (IDD_CUTDIALOG), *this, (DLGPROC) CutDialogProc))
	{
		if( FileBuffer.Length() - iCutOffset >= iCutNumberOfBytes )
		{
			int newlen = FileBuffer.Length () - iCutNumberOfBytes;
			
			switch (iCutMode)
			{
			case BST_CHECKED:
				{
					
					int iDestinationLength = byte_to_bytecode_destinationlength ((char*) &(FileBuffer[iCutOffset]), iCutNumberOfBytes);
					HGLOBAL hGlobal = GlobalAlloc (GHND, iDestinationLength*sizeof(TCHAR));
					if (hGlobal != NULL)
					{
						SetCursor (LoadCursor (NULL, IDC_WAIT));
						TCHAR* pd = (TCHAR*) GlobalLock (hGlobal);
						translate_bytes_to_bytecode (pd, &(FileBuffer[iCutOffset]), iCutNumberOfBytes);
						GlobalUnlock (hGlobal);
						OpenClipboard (*this);
						EmptyClipboard ();
						SetClipboardData (CF_UNICODETEXT, hGlobal);
						CloseClipboard ();
						SetCursor (LoadCursor (NULL, IDC_ARROW));
					}
					else
					{
						
						MessageBox(LoadString(IDS_CUT_CLIP_NO_MEMORY),LoadString(IDS_TITLE_CUT_ERROR), MB_OK | MB_ICONERROR);
						return 0;
					}
					break;
				}
				
			default:
				break;
			}
			
			if (FileBuffer.RemoveAt (iCutOffset, iCutNumberOfBytes) == FALSE)
			{
				long m = iCutOffset;
				for(m = m;m<iCutOffset + iCutNumberOfBytes;m++)
					//vChanges.remove(m);
					vChanges.erase(vChanges.begin()+m);
				MessageBox(LoadString(IDS_CUT_CANT_CUT),LoadString(IDS_TITLE_CUT_ERROR), MB_OK | MB_ICONERROR);
				return FALSE;
			}
			iCurrentByte = iCutOffset;
			if (iCurrentByte > (FileBuffer.Upper ()))
				iCurrentByte = (FileBuffer.Upper ());
			if (iCurrentByte<0)
				iCurrentByte=0;
			iFileChanged = TRUE;
			bFilestatusChanged = TRUE;
			bSelected = FALSE;
			update_size_change ();
			repaint ();
		}
		else
		{
			
			MessageBox(LoadString(IDS_CUT_OVERFLOW),LoadString(IDS_TITLE_CUT_ERROR), MB_OK | MB_ICONERROR);
		}
	}
	return 0;
}

int Translhextion::edit_copy ()
{
	if (!bSelected)
	{
		
		iCopyStartOffset = iCurrentByte;
		iCopyEndOffset = iCurrentByte;
	}
	else
	{
		
		if (iEndOfSelection >= iStartOfSelection)
		{
			iCopyStartOffset = iStartOfSelection;
			iCopyEndOffset = iEndOfSelection;
		}
		else
		{
			iCopyStartOffset = iEndOfSelection;
			iCopyEndOffset = iStartOfSelection;
		}
	}

	if (DialogBox (hInstance, MAKEINTRESOURCE (IDD_COPYDIALOG), *this, (DLGPROC) CopyDialogProc) != FALSE)
	{
		
		iStartOfSelection = iCopyStartOffset;
		iEndOfSelection = iCopyEndOffset;
		if (iEndOfSelection >= iStartOfSelection)
		{
			int iDestinationLength = byte_to_bytecode_destinationlength ((char*) &(FileBuffer[iStartOfSelection]), iEndOfSelection-iStartOfSelection+1);
			HGLOBAL hGlobal = GlobalAlloc (GHND, iDestinationLength);
			if (hGlobal != NULL)
			{
				SetCursor (LoadCursor (NULL, IDC_WAIT));
				TCHAR* pd = (TCHAR*) GlobalLock (hGlobal);
				translate_bytes_to_bytecode (pd, &(FileBuffer[iStartOfSelection]), iEndOfSelection-iStartOfSelection+1);
				GlobalUnlock (hGlobal);
				OpenClipboard (*this);
				EmptyClipboard ();
				SetClipboardData (CF_TEXT, hGlobal);
				CloseClipboard ();
				SetCursor (LoadCursor (NULL, IDC_ARROW));
			}
			else
				MessageBoxA (*this, "Not enough memory for copying.", "Copy error:", MB_OK | MB_ICONERROR);
		}
		else
		{
			MessageBoxA (*this, "Ending offset is smaller than starting offset.", "Copy error:", MB_OK | MB_ICONERROR);
		}
	}
	adjust_view_for_selection ();
	return 1;
}

int Translhextion::thingy_copy ()
{
	if (!bSelected)
	{
		
		iCopyStartOffset = iCurrentByte;
		iCopyEndOffset = iCurrentByte;
	}
	else
	{
		
		if (iEndOfSelection >= iStartOfSelection)
		{
			iCopyStartOffset = iStartOfSelection;
			iCopyEndOffset = iEndOfSelection;
		}
		else
		{
			iCopyStartOffset = iEndOfSelection;
			iCopyEndOffset = iStartOfSelection;
		}
	}

	if (DialogBox (hInstance, MAKEINTRESOURCE (IDD_COPYDIALOG), *this, (DLGPROC) CopyDialogProc) != FALSE)
	{
		iStartOfSelection = iCopyStartOffset;
		iEndOfSelection = iCopyEndOffset;
		if (iEndOfSelection >= iStartOfSelection)
		{
			int i = 0;
			iDumpStart = iStartOfSelection;
			iDumpEnd = iEndOfSelection;
			std::vector<_tstring> vDumpSize((iDumpEnd-iDumpStart)+1);
			vHexdoc = vDumpSize;
			vDumpSize = vEmpty;
			SetCursor (LoadCursor (NULL, IDC_WAIT));
			HWND progressdialog = CreateDialog(hInstance, MAKEINTRESOURCE (IDD_PROGRESSDIALOG),*this,ProgressDialogProc);
			//SetFocus(progressdialog);
			SetWindowTextA(progressdialog,"Script Dump Preparation...");
			SetWindowTextA(GetDlgItem(progressdialog,IDC_PROGRESS1TITLE),"Queuing bytes...");
			progress1 = GetDlgItem(progressdialog,IDC_PROGRESS1);
			SetProgressRange(progress1,0,vHexdoc.size());
			if(vHexdoc.size() >= 10000)//this could be better
			{
				iIncrementStep = vHexdoc.size() / 1000;
			}
			else if(vHexdoc.size() >= 1000)//this could be better
			{
				iIncrementStep = vHexdoc.size() / 100;
			}
			else if(vHexdoc.size() >= 100)
			{
				iIncrementStep = vHexdoc.size() / 10;
			}
			else
			{
				iIncrementStep = 2; 
			}
			SetProgressStep(progress1,iIncrementStep);  
			for(i = iDumpStart;i<=iDumpEnd;i++)
			{
				iProgressPos++;
				if(progress1 != NULL && iProgressPos % iIncrementStep == 0)
				{
					StepProgress(progress1);	
				}
				vHexdoc[i - iDumpStart] = hex_char(FileBuffer[i]);
			}
			DestroyWindow(progressdialog);
			iProgressPos = 0;
			iIncrementStep = 0;
			progress1 = NULL;
			long filesize = vHexdoc.size();
			bCleanScript = true;
			progressdialog = CreateDialog(hInstance, MAKEINTRESOURCE (IDD_2PROGRESSDIALOG),*this,ProgressDialogProc);
			SetWindowTextA(progressdialog,"Script Dump Progress...");
			SetWindowTextA(GetDlgItem(progressdialog,IDC_PROGRESS1TITLE),"Translating...");
			progress1 = GetDlgItem(progressdialog,IDC_PROGRESS1);
			progress2 = GetDlgItem(progressdialog,IDC_PROGRESS2);
			SetProgressRange(progress1,0,vHexdoc.size());
			if(vHexdoc.size() >= 10000)//this could be better
			{
				iIncrementStep = vHexdoc.size() / 1000;
			}
			else if(vHexdoc.size() >= 1000)//this could be better
			{
				iIncrementStep = vHexdoc.size() / 100;
			}
			else if(vHexdoc.size() >= 100)
			{
				iIncrementStep = vHexdoc.size() / 10;
			}
			else
			{
				iIncrementStep = 2; 
			}
			SetProgressStep(progress1,iIncrementStep);  
			long numbytes = vHexdoc.size();
			table.translate(vHexdoc);
			SetProgressPos(progress1,numbytes);
			iProgressPos = 0;
			SetProgressRange(progress2,0,vHexdoc.size());
			if(vHexdoc.size() >= 10000)//this could be better
			{
				iIncrementStep = vHexdoc.size() / 1000;
			}
			else if(vHexdoc.size() >= 1000)//this could be better
			{
				iIncrementStep = vHexdoc.size() / 100;
			}
			else if(vHexdoc.size() >= 100)
			{
				iIncrementStep = vHexdoc.size() / 10;
			}
			else
			{
				iIncrementStep = 2; 
			}
			SetProgressStep(progress2,iIncrementStep);  
			SetWindowTextA(GetDlgItem(progressdialog,IDC_PROGRESS2TITLE),"Formatting...");
			enscript(vHexdoc);
			progress1 = NULL;
			progress2 = NULL;
			iIncrementStep = 0;
			iProgressPos = 0;
			DestroyWindow(progressdialog);
			bCleanScript = false;
			SetCursor (LoadCursor (NULL, IDC_ARROW));
			_tstring clipdata = L"";
			//clipdata = "";
			int m = 0;
			for(m = 0;m<(int)vHexdoc.size();m++)
			{
				clipdata += vHexdoc[m];
			}
			HGLOBAL hGlobal = GlobalAlloc (GHND, clipdata.length());
			if (hGlobal != NULL)
			{
				SetCursor (LoadCursor (NULL, IDC_WAIT));
				TCHAR* pd = (TCHAR*) GlobalLock (hGlobal);
				strcpy(pd,clipdata.c_str());
				GlobalUnlock (hGlobal);
				OpenClipboard (*this);
				EmptyClipboard ();
				SetClipboardData (CF_TEXT, hGlobal);
				CloseClipboard ();
				SetCursor (LoadCursor (NULL, IDC_ARROW));
			}
			else
				MessageBoxA (*this, "Not enough memory for copying.", "Copy error:", MB_OK | MB_ICONERROR);
		}
		else
		{
			MessageBoxA (*this, "Ending offset is smaller than starting offset.", "Copy error:", MB_OK | MB_ICONERROR);
		}
	}
	adjust_view_for_selection ();
	return 1;
}

int Translhextion::copy_hexdump ()
{
	if (FileBuffer.Length() <= 0)
	{
		MessageBoxA (*this, "Cannot hexdump an empty file.", "Hexdump error:", MB_OK | MB_ICONERROR);
		return 0;
	}
	if( !bSelected )
	{
		
		iCopyHexdumpDialogStart = 0;
		iCopyHexdumpDialogEnd = ((FileBuffer.Upper())/iBytesPerLine)*iBytesPerLine;
	}
	else
	{
		if( iEndOfSelection < iStartOfSelection )
		{
			int i = iEndOfSelection;
			iEndOfSelection = iStartOfSelection;
			iStartOfSelection = i;
		}
		iCopyHexdumpDialogStart = ( iStartOfSelection / iBytesPerLine ) * iBytesPerLine;
		iCopyHexdumpDialogEnd = ( iEndOfSelection / iBytesPerLine ) * iBytesPerLine;
	}

	if (DialogBox (hInstance, MAKEINTRESOURCE (IDD_HEXDUMPDIALOG), *this, (DLGPROC) CopyHexdumpDialogProc) != FALSE)
	{
		
		SetCursor (LoadCursor (NULL, IDC_WAIT));
		if (iCopyHexdumpDialogStart % iBytesPerLine != 0 || iCopyHexdumpDialogEnd % iBytesPerLine != 0)
		{
			MessageBoxA (*this, "Offsets must be multiples of\nthe number of bytes per iLine.", "Hexdump error:", MB_OK | MB_ICONERROR);
			return 0;
		}
		
		int linecount = (iCopyHexdumpDialogEnd - iCopyHexdumpDialogStart) / iBytesPerLine + 1;
		
		
		int buflen = linecount * (iCharsPerLine+2) + 1;
		
		int a,b,k,m,n,j,l;
		TCHAR buf1[128], buf2[128];
		TCHAR* pMem = new TCHAR[buflen];
		for (n=0; n < buflen; n++)
			pMem[n] = ' ';
		
		b = iCopyHexdumpDialogEnd;
				
		for (k = 0, a = iCopyHexdumpDialogStart; a <= b; a += iBytesPerLine, k += iCharsPerLine + 2)
		{
			
			sprintf (buf1, _T("%%%d.%dx"), iOffsetLength, iOffsetLength);
			for (m = 0; m < iByteSpace; m++)
				strcat (buf1, _T(" "));
			sprintf (buf2, buf1, a); 
			l = 0; 
			n = 0;
			while (buf2[n] != '\0')
				pMem[k + (l++)] = buf2[n++]; 
			
			for (j = 0; j < iBytesPerLine; j++)
			{
				if (a+j > FileBuffer.Upper ())
				{
					
					pMem[k + l + j*3    ] = ' ';
					pMem[k + l + j*3 + 1] = ' ';
					pMem[k + l + j*3 + 2] = ' ';
					
					pMem[k + l + iBytesPerLine*3 + iCharSpace + j] = ' ';
				}
				else
				{
					
					sprintf (buf1, _T("%2.2x "), FileBuffer[a + j]);
					pMem[k + l + j*3    ] = buf1[0];
					pMem[k + l + j*3 + 1] = buf1[1];
					pMem[k + l + j*3 + 2] = buf1[2];
					
					if( iCharacterSet == OEM_FIXED_FONT && FileBuffer[a + j] != 0 )
					{
						pMem[k + l + iBytesPerLine*3 + iCharSpace + j] = FileBuffer[a + j];
					}
					else if( (FileBuffer[a + j] >= 32 && FileBuffer[a + j] <= 126) || (FileBuffer[a + j]>=160 && FileBuffer[a + j] <= 255) || (FileBuffer[a + j] >= 145 && FileBuffer[a + j] <= 146) )
					{
						pMem[k + l + iBytesPerLine*3 + iCharSpace + j] = FileBuffer[a + j];
					}
					else
					{
						pMem[k + l + iBytesPerLine*3 + iCharSpace + j] = '.';
					}
				}
			}
			pMem[k + iCharsPerLine    ] = '\r';
			pMem[k + iCharsPerLine + 1] = '\n';
		}
		pMem[buflen-1] = '\0';
		
		SetCursor (LoadCursor (NULL, IDC_ARROW));
		if (iCopyHexdumpMode == BST_CHECKED)
		{
			
			HGLOBAL hGlobal = GlobalAlloc (GHND, buflen);
			if (hGlobal != NULL)
			{
				char* pDest = (char*) GlobalLock (hGlobal);
				memcpy (pDest, pMem, buflen);
				GlobalUnlock (hGlobal);
				OpenClipboard (*this);
				EmptyClipboard ();
				SetClipboardData (CF_TEXT, hGlobal);
				CloseClipboard ();
			}
			else
				MessageBoxA (*this, "Not enough memory to hexdump to clipboard.", "Hexdump error:", MB_OK | MB_ICONERROR);
		}
		else
		{
			
			TCHAR cFileName[_MAX_PATH];
			TCHAR szTitleName[_MAX_FNAME + _MAX_EXT];
			strcpy (cFileName, _T("hexdump.txt"));
			OPENFILENAME ofn;
			ofn.lStructSize = sizeof (OPENFILENAME);
			ofn.hwndOwner = *this;
			ofn.hInstance = NULL;
			ofn.lpstrFilter = _T("All Files (*.*)\0*.*\0\0");
			ofn.lpstrCustomFilter = NULL;
			ofn.nMaxCustFilter = 0;
			ofn.nFilterIndex = 0;
			ofn.lpstrFile = cFileName;
			ofn.nMaxFile = _MAX_PATH;
			ofn.lpstrFileTitle = szTitleName;
			ofn.nMaxFileTitle = _MAX_FNAME + _MAX_EXT;
			ofn.lpstrInitialDir = NULL;
			ofn.lpstrTitle = NULL;
			ofn.Flags = OFN_HIDEREADONLY | OFN_CREATEPROMPT | OFN_OVERWRITEPROMPT;
			ofn.nFileOffset = 0;
			ofn.nFileExtension = 0;
			ofn.lpstrDefExt = NULL;
			ofn.lCustData = 0L;
			ofn.lpfnHook = NULL;
			ofn.lpTemplateName = NULL;
			if (GetSaveFileName (&ofn))
			{
				int iFileHandle;
				if ((iFileHandle = _topen (cFileName, _O_RDWR|_O_CREAT|_O_TRUNC|_O_BINARY,_S_IREAD|_S_IWRITE)) != -1)
				{
					
					if ((_write (iFileHandle, pMem, buflen-1)) != -1)
					{
						MessageBox (LoadString(IDS_NOTICE_HEXDUMP_SAVED), LoadString(IDS_TITLE_NOTICE), MB_OK | MB_ICONINFORMATION);
					}
					else
						MessageBoxA (*this, "Could not save Hexdump.", "Hexdump error:", MB_OK | MB_ICONERROR);
					_close (iFileHandle);
				}
				else
					MessageBoxA (*this, "Could not save Hexdump.", "Hexdump error:", MB_OK | MB_ICONERROR);
			}
			repaint ();
		}
		delete [] pMem;
	}
	return 1;
}

int Translhextion::fast_paste ()
{
	CParseFastDlg dlg(*this);

	if( iInsertMode ) iPasteMode = 2;
	else iPasteMode = 1;
	if (dlg.DoModal()==IDOK/*DialogBox (hInstance, MAKEINTRESOURCE (IDD_FASTPASTE_DIALOG), *this, (DLGPROC) FastPasteDialogProc)*/)
	{
		switch( iPasteMode )
		{
		case 1:
			{
				u8* pcPastestring;
				
				int iDestinationLength;
				if( iPasteAsText == TRUE )
				{
					iDestinationLength = _tcslen( pcPasteText );
					pcPastestring = new u8[ iDestinationLength ];
					memcpy( pcPastestring, pcPasteText, iDestinationLength*sizeof(*pcPastestring) );
				}
				else
				{
					iDestinationLength = bytecode_translate (&pcPastestring, pcPasteText, _tcslen(pcPasteText), iCharacterSet, iBinaryMode);
				}
				if (iDestinationLength > 0)
				{
					if (FileBuffer.Length()-iCurrentByte >= (iPasteSkip+iDestinationLength)*iPasteTimes)
					{
						
						SetCursor (LoadCursor (NULL, IDC_WAIT));
						int i,k;
						for (k=0; k<iPasteTimes; k++)
						{
							for (i=0; i<iDestinationLength; i++)
							{
								FileBuffer[(iCurrentByte+k*(iPasteSkip+iDestinationLength))+i] = pcPastestring[i];
								vChanges[(iCurrentByte+k*(iPasteSkip+iDestinationLength))+i] = COLORCHANGE;
							}
						}
						SetCursor (LoadCursor (NULL, IDC_ARROW));
						iFileChanged = TRUE;
						bFilestatusChanged = TRUE;
					}
					else
					{
						MessageBox(LoadString(IDS_PASTE_OVERFLOW),LoadString(IDS_TITLE_PASTE_ERROR), MB_OK | MB_ICONERROR);
					}
					delete [] pcPastestring;
				}
				delete [] pcPasteText;
				repaint ();
				break;
			}

		case 2: 
			{
				u8* pcPastestring;
				int iDestinationLength;
				if( iPasteAsText == TRUE )
				{
					iDestinationLength = _tcslen( pcPasteText );
					pcPastestring = new u8[ iDestinationLength ];
					memcpy( pcPastestring, pcPasteText, iDestinationLength*sizeof(*pcPastestring) );
				}
				else
				{
					iDestinationLength = bytecode_translate (&pcPastestring, pcPasteText, strlen (pcPasteText), iCharacterSet, iBinaryMode);
				}
				if (iDestinationLength > 0)
				{
					
					SetCursor (LoadCursor (NULL, IDC_WAIT));
					int i, k;
					for( k = 0,i=iCurrentByte; k < iPasteTimes; k++ )
					{
						if(!FileBuffer.InsertExpandOn(iCurrentByte,(unsigned char*)pcPastestring,0,iDestinationLength))
						{
							delete [] pcPastestring;
							delete [] pcPasteText;
							SetCursor (LoadCursor (NULL, IDC_ARROW));
							MessageBox(LoadString(IDS_PASTE_OUT_OF_MEMORY),LoadString(IDS_TITLE_PASTE_ERROR), MB_OK | MB_ICONERROR);
							update_size_change ();
							return FALSE;
						}
						iFileChanged = TRUE;
						bFilestatusChanged = TRUE;
						long m = iCurrentByte;
						for(m = m;m<iCurrentByte+iDestinationLength;m++)
							//vChanges.insert(COLORCHANGE,m);
							vChanges.insert(vChanges.begin()+m,COLORCHANGE);
						iCurrentByte+=iDestinationLength+iPasteSkip;
					}
					iCurrentByte=i;
					iFileChanged = TRUE;
					bFilestatusChanged = TRUE;
					update_size_change ();
					delete [] pcPastestring;
					SetCursor (LoadCursor (NULL, IDC_ARROW));
				}
				delete [] pcPasteText;
				repaint ();
				break;
			}

		default:
			break;
		}
	}
	return 0;
}


int Translhextion::edit_paste ()
{
	if( iInsertMode )
		iPasteMode = 2;
	else
		iPasteMode = 1;
	if (DialogBox (hInstance, MAKEINTRESOURCE (IDD_PASTEDIALOG), *this, (DLGPROC) PasteDialogProc))
	{
		switch( iPasteMode )
		{
		case 1: 
			{
				u8* pcPastestring;
				
				int iDestinationLength;
				if( iPasteAsText == TRUE )
				{
					iDestinationLength = strlen( pcPasteText );
					pcPastestring = new u8[ iDestinationLength ];
					memcpy( pcPastestring, pcPasteText, iDestinationLength );
				}
				else
				{
					iDestinationLength = bytecode_translate (&pcPastestring, pcPasteText, strlen (pcPasteText), iCharacterSet, iBinaryMode);
				}
				if (iDestinationLength > 0)
				{
					
					if (FileBuffer.Length()-iCurrentByte >= (iPasteSkip+iDestinationLength)*iPasteTimes)
					{
						
						SetCursor (LoadCursor (NULL, IDC_WAIT));
						int i,k;
						for (k=0; k<iPasteTimes; k++)
						{
							for (i=0; i<iDestinationLength; i++)
							{
								FileBuffer[(iCurrentByte+k*(iPasteSkip+iDestinationLength))+i] = pcPastestring[i];
								vChanges[(iCurrentByte+k*(iPasteSkip+iDestinationLength))+i] = COLORCHANGE;
							}
						}
						SetCursor (LoadCursor (NULL, IDC_ARROW));
						iFileChanged = TRUE;
						bFilestatusChanged = TRUE;
					}
					else
					{
						MessageBox(_T("There is not enough space in the file for overwriting."), LoadString(IDS_TITLE_PASTE_ERROR), MB_OK | MB_ICONERROR);
					}
					delete [] pcPastestring;
				}
				delete [] pcPasteText;
				repaint ();
				break;
			}

		case 2: 
			{
				u8* pcPastestring;
				int iDestinationLength;
				if( iPasteAsText == TRUE )
				{
					iDestinationLength = strlen( pcPasteText );
					pcPastestring = new u8[ iDestinationLength ];
					memcpy( pcPastestring, pcPasteText, iDestinationLength );
				}
				else
				{
					iDestinationLength = bytecode_translate( &pcPastestring, pcPasteText, strlen( pcPasteText ), iCharacterSet, iBinaryMode );
				}
				if( iDestinationLength > 0 )
				{
					
					SetCursor( LoadCursor( NULL, IDC_WAIT ) );
					int i, k;
					for( k = 0,i=iCurrentByte; k < iPasteTimes; k++ )
					{
						if(!FileBuffer.InsertExpandOn(iCurrentByte,(unsigned char*)pcPastestring,0,iDestinationLength))
						{
							delete [] pcPastestring;
							delete [] pcPasteText;
							SetCursor (LoadCursor (NULL, IDC_ARROW));
							MessageBox(_T("Not enough memory for insertion."), LoadString(IDS_TITLE_PASTE_ERROR), MB_OK | MB_ICONERROR);
							update_size_change ();
							return FALSE;
						}
						iFileChanged = TRUE;
						bFilestatusChanged = TRUE;
						long m = iCurrentByte;
						for(m = m;m<iCurrentByte+iDestinationLength;m++)
							//vChanges.insert(COLORCHANGE,m);
							vChanges.insert(vChanges.begin()+m,COLORCHANGE);
						iCurrentByte+=iDestinationLength+iPasteSkip;
					}
					iCurrentByte=i;
					iFileChanged = TRUE;
					bFilestatusChanged = TRUE;
					update_size_change ();
					delete [] pcPastestring;
					SetCursor (LoadCursor (NULL, IDC_ARROW));
				}
				else
				{
					delete [] pcPasteText;
					MessageBox(_T("Insertion of array of size 0."), LoadString(IDS_TITLE_PASTE_ERROR), MB_OK | MB_ICONERROR);
					update_size_change ();
					return FALSE;
				}
				
				delete [] pcPasteText;
				repaint ();
				break;
			}

		default:
			break;
		}
	}
	return 0;
}

int Translhextion::select_all ()
{
	if (FileBuffer.Length() <= 0)
		return 0;
	bSelected = TRUE;
	iStartOfSelection = 0;
	iEndOfSelection = FileBuffer.Upper ();
	adjust_view_for_selection ();
	repaint ();
	return 1;
}

int Translhextion::select_block ()
{
	iEndOfSelSetting = iStartOfSelSetting = iCurrentByte;
	if (DialogBox (hInstance, MAKEINTRESOURCE (IDD_SELECT_BLOCK_DIALOG), *this, (DLGPROC) SelectBlockDialogProc))
	{
		if (iStartOfSelSetting<0 || iStartOfSelSetting>(FileBuffer.Upper ()) || iEndOfSelSetting<0 || iEndOfSelSetting>(FileBuffer.Upper ()))
		{
			MessageBoxA (*this, "Specified offset is not valid.", "Select block error:", MB_OK | MB_ICONERROR);
			return 0;
		}
		iStartOfSelection = iStartOfSelSetting;
		iEndOfSelection = iEndOfSelSetting;
		bSelected = TRUE;
		adjust_view_for_selection ();
		repaint ();
	}
	return 0;
}

void Translhextion::fill_with()
{
	tmpstart=iStartOfSelection;tmpend=iEndOfSelection;
		if (DialogBox(hInstance, MAKEINTRESOURCE (IDD_FILL_WITH), *this, (DLGPROC) FillWithDialogProc))
	{
		SetCursor(LoadCursor(NULL,IDC_WAIT));
		TCHAR (*fnc)(const int&);
		long i,q,qmax;
		if (TypeOfCurrent)
		{
			fnc=file;
			qmax = FWFilelen;
		}
		else 
		{
			fnc=input;
			qmax=buflen;
		}
		if (iStartOfSelection>iEndOfSelection)
			sswap(tmpstart,tmpend);
		switch(asstyp)
		{
			case 0:
			{
				for(q=0,i=tmpstart;i<=tmpend;i++)
				{
					FileBuffer[(int)i]=(u8)fnc(q);
					vChanges[(int)i] = COLORCHANGE;
					q++;
					q%=qmax;
				}
			}
				break;
			case 1:
			{
				for(q=0,i=tmpstart;i<=tmpend;i++)
				{
					FileBuffer[(int)i]|=fnc(q);
					vChanges[(int)i] = COLORCHANGE;
					q++;
					q%=qmax;
				}
			}
				break;
			case 2:
			{
				for(q=0,i=tmpstart;i<=tmpend;i++)
				{
					FileBuffer[(int)i]&=fnc(q);
					vChanges[(int)i] = COLORCHANGE;
					q++;
					q%=qmax;
				}
			}
			break;
			case 3:
			{
				for(q=0,i=tmpstart;i<=tmpend;i++)
				{
					FileBuffer[(int)i]^=fnc(q);
					vChanges[(int)i] = COLORCHANGE;
					q++;
					q%=qmax;
				}
			}
			break;
		}
		if (TypeOfCurrent) _close(FWFile);
		iFileChanged = TRUE;
		bFilestatusChanged = TRUE;
		SetCursor (LoadCursor (NULL, IDC_ARROW));
		repaint ();
	}
}


void Translhextion::save_selection_as()
{
	TCHAR cFileName[_MAX_PATH];
	TCHAR szTitleName[_MAX_FNAME + _MAX_EXT];
	OPENFILENAME ofn;
	szTitleName[0] =cFileName[0] = '\0';
	ofn.lStructSize = sizeof (OPENFILENAME);
	ofn.hwndOwner = *this;
	ofn.hInstance = NULL;
	ofn.lpstrFilter = _T("All Files (*.*)\0*.*\0\0");
	ofn.lpstrCustomFilter = NULL;
	ofn.nMaxCustFilter = 0;
	ofn.nFilterIndex = 0;
	ofn.lpstrFile = cFileName;
	ofn.nMaxFile = _MAX_PATH;
	ofn.lpstrFileTitle = szTitleName;
	ofn.nMaxFileTitle = _MAX_FNAME + _MAX_EXT;
	ofn.lpstrInitialDir = NULL;
	ofn.lpstrTitle = _T("Save Selection As");
	ofn.Flags = OFN_HIDEREADONLY | OFN_CREATEPROMPT | OFN_OVERWRITEPROMPT;
	ofn.nFileOffset = 0;
	ofn.nFileExtension = 0;
	ofn.lpstrDefExt = NULL;
	ofn.lCustData = 0L;
	ofn.lpfnHook = NULL;
	ofn.lpTemplateName = NULL;
	if (GetSaveFileName (&ofn))
	{
		int iFileHandle;
		if ((iFileHandle = _topen (cFileName, _O_RDWR|_O_CREAT|_O_TRUNC|_O_BINARY,_S_IREAD|_S_IWRITE)) != -1)
		{
			SetCursor (LoadCursor (NULL, IDC_WAIT));
			if(iStartOfSelection>iEndOfSelection)sswap(iStartOfSelection,iEndOfSelection);
			if (!((_write (iFileHandle, &FileBuffer[iStartOfSelection], iEndOfSelection-iStartOfSelection+1)) != -1))
				MessageBoxA (*this, "Could not save selection file.", "Save selection as error:", MB_OK | MB_ICONERROR);
			SetCursor (LoadCursor (NULL, IDC_ARROW));
			_close (iFileHandle);
		}
		else
			MessageBoxA (NULL, "Could not save selection file.", "Save selection as error:", MB_OK | MB_ICONERROR);
	}
	repaint ();
}

//OFFSET

int Translhextion::_Goto()
{
	//if( filename[0] == '\0' )
	//	return 0;
	CGoToDlg dlg(*this);

	if(dlg.DoModal()==IDOK/* DialogBox( hInstance, MAKEINTRESOURCE(IDD_GOTODIALOG), *this, (DLGPROC) GoToDialogProc ) */)
	{
		int offset, i = 0, r = 0;
		if( pcGotoDialogBuffer[0] == '+' || pcGotoDialogBuffer[0] == '-' )
		{
			r = 1;
		}

		if( sscanf( &pcGotoDialogBuffer[r], _T("x%X"), &offset ) == 0 )
		{
			if( sscanf ( &pcGotoDialogBuffer[r], _T("%d"), &offset ) == 0 )
			{
				i = -1;
			}
		}
		if( i==-1 )
		{
			MessageBoxA (*this, "Offset is not recognized.", "Go to error:", MB_OK | MB_ICONERROR);
			return 0;
		}
		

		if( r == 1 )
		{
			
			if ( pcGotoDialogBuffer[0] == '-' )
				r = -1;

			if( iCurrentByte + r * offset >= 0 && iCurrentByte + r * offset <= (FileBuffer.Upper ()) )
			{
				iCurrentByte = iCurrentByte + r * offset;
				iCurrentLine = (iCurrentByte / iBytesPerLine);
				update_vertical_scrollbar();
				repaint();
			}
			else
				MessageBoxA( *this, "Invalid offset.", "Go to error:", MB_OK | MB_ICONERROR );
		}
		else
		{
			if(iOffsetMode == LOROM)
				offset = fromLOROM(offset);
			else if(iOffsetMode == HIROM)
				offset = fromHIROM(offset);
			
			if( offset >= 0 && offset <= (FileBuffer.Upper ()) )
			{
				iCurrentByte = offset;
				iCurrentLine = (iCurrentByte / iBytesPerLine);
				update_vertical_scrollbar();
				repaint();
			}
			else
				MessageBoxA( *this, "Invalid offset.", "Go to error:", MB_OK | MB_ICONERROR );
		}
	}
	return 1;
}

int Translhextion::manipulate_bits ()
{
	if (FileBuffer.Length() == 0)
	{
		MessageBoxA (*this, "File is empty.", "Manipulate bits error:", MB_OK | MB_ICONERROR);
		return 0;
	}
	if (iCurrentByte<0 || iCurrentByte>(FileBuffer.Upper ()))
	{
		MessageBoxA (*this, "Must choose a byte in the file.", "Manipulate bits error:", MB_OK | MB_ICONERROR);
		return 0;
	}
	cBitValue = FileBuffer[iCurrentByte];
	iManipPos = iCurrentByte;
	if (DialogBox (hInstance, MAKEINTRESOURCE (IDD_MANIPBITSDIALOG), *this, (DLGPROC) BitManipDialogProc))
	{
		SetCursor (LoadCursor (NULL, IDC_WAIT));
		SetCursor (LoadCursor (NULL, IDC_ARROW));
		FileBuffer[iCurrentByte] = cBitValue;
		vChanges[iCurrentByte] = COLORCHANGE;
		iFileChanged = TRUE;
		bFilestatusChanged = TRUE;
		repaint ();
	}
	return 1;
}

int Translhextion::compare_arrays (char* ps, int sl, char* pd, int dl)
{
	int i, diff=0, type=1;
	for (i=0; i<sl && i<dl; i++)
	{
		switch (type)
		{
		case 0:
			if (ps[i]==pd[i])
			{
				diff++;
				type = 1;
			}
			break;

		case 1:
			if (ps[i]!=pd[i])
			{
				type = 0;
			}
			break;
		}
	}
	if (type == 0)
		diff++;
	return diff;
}

int Translhextion::get_diffs (char* ps, int sl, char* pd, int dl, intpair* pdiff)
{
	int i, diff=0, type=1;
	
	for (i=0; i<sl && i<dl; i++)
	{
		switch (type)
		{
		case 0:
			
			if (ps[i]==pd[i])
			{
				
				pdiff[diff].y = i-1; 
				diff++;
				type = 1;
			}
			
			break;

		case 1:
			
			if (ps[i]!=pd[i])
			{
				
				pdiff[diff].x = i; 
				type = 0;
			}
			
			break;
		}
	}
	if (type == 0) 
	{
		pdiff[diff].y = i-1;
		diff++;
	}
	return diff;
}

int Translhextion::compare ()
{
	if (FileBuffer.Length() <= 0)
	{
		MessageBoxA (*this, "Current file is empty.", "Compare error:", MB_OK | MB_ICONERROR);
		return 0;
	}

	CFileDialog dlg;
	dlg.Create(*this,LoadString(IDS_FILTER_ALL),LoadString(IDS_FILTER_COMPARE_TITLE),OFN_HIDEREADONLY | OFN_FILEMUSTEXIST);

	if (dlg.DoModal()/*GetOpenFileName (&ofn)*/)
	{
		int iFileHandle;
		if ((iFileHandle = _topen (dlg.GetFileName()/*cFileName*/,_O_RDONLY|_O_BINARY,_S_IREAD|_S_IWRITE)) != -1)
		{
			int iFileLength = _filelength (iFileHandle);
			iDestFileLength = iFileLength;
			iSrcFileLength = FileBuffer.Length()-iCurrentByte;
			char* cmpdata = new char[iFileLength];
			
			if (_read (iFileHandle, cmpdata, iFileLength) != -1)
			{
				int diff;
				if ((diff = compare_arrays ((char*) &(FileBuffer[iCurrentByte]), FileBuffer.Length()-iCurrentByte, cmpdata, iFileLength)) == 0)
				{
					
					MessageBox (LoadString(IDS_NOTICE_DATA_MATCHES), LoadString(IDS_TITLE_NOTICE), MB_OK | MB_ICONINFORMATION);
				}
				else
				{
					
					intpair* pdiff = new intpair[diff];
					get_diffs ((char*) &(FileBuffer[iCurrentByte]), FileBuffer.Length()-iCurrentByte, cmpdata, iFileLength, pdiff);
					pdiffChoice = pdiff;
					iDiffNum = diff;
					if (DialogBox (hInstance, MAKEINTRESOURCE (IDD_CHOOSEDIFFDIALOG), *this, (DLGPROC) ChooseDiffDialogProc))
					{
						iStartOfSelection = iCurrentByte+pdiff[iDiffNum].x;
						iEndOfSelection = iCurrentByte+pdiff[iDiffNum].y;
						bSelected = TRUE;
						iCurrentByte = iCurrentByte+pdiff[iDiffNum].x;
						adjust_view_for_selection ();
						repaint ();
					}
					delete [] pdiff;
				}
				_close (iFileHandle);
				delete [] cmpdata;
				return TRUE;
			}
			else
			{
				delete [] cmpdata;
				_close (iFileHandle);
				MessageBoxA (*this, "Error while reading from file.", "Compare file error:", MB_OK | MB_ICONERROR);
				return FALSE;
			}
		}
	}
	return 1;
}

//INSERT

int Translhextion::toggle_insertmode ()
{
	iInsertMode = (iInsertMode) ? FALSE : TRUE;
	update_window_status();
	return 1;
}

int Translhextion::edit_enterdecimalvalue ()
{
	iDecValDialogOffset = iCurrentByte;
	if (iCurrentByte <= (FileBuffer.Upper ()) && iCurrentByte >= 0)
		iDecValDialogValue = (int) FileBuffer[iCurrentByte];
	else
		iDecValDialogValue = 0;
	if (DialogBox (hInstance, MAKEINTRESOURCE (IDD_DECIMALDIALOG), *this, (DLGPROC) EnterDecimalValueDialogProc))
	{
		if (iDecValDialogOffset<0 || iDecValDialogOffset>(FileBuffer.Upper ()))
		{
			MessageBoxA (*this, "Invalid starting offset.", "Enter decimal value error:", MB_OK | MB_ICONERROR);
			return 0;
		}
		if (iDecValDialogOffset+iDecValDialogSize*iDecValDialogTimes > (FileBuffer.Upper ()))
		{
			MessageBoxA (*this, "Not enough space in file for writing decimal values.", "Enter decimal value error:", MB_OK | MB_ICONERROR);
			return 0;
		}
		SetCursor (LoadCursor (NULL, IDC_WAIT));
		int i, k = 0;
		for (i = 0; i < iDecValDialogTimes; i++)
		{
			if (iDecValDialogOffset + k > FileBuffer.Upper ())
			{
				MessageBoxA (*this, "Reached end of file prematurely.", "Enter decimal value error:", MB_OK | MB_ICONERROR);
				break;
			}

			if (iBinaryMode == LITTLE_ENDIAN)
			{
				switch (iDecValDialogSize)
				{
				case 1:
					FileBuffer[iDecValDialogOffset + k] = iDecValDialogValue;
					vChanges[iDecValDialogOffset + k] = COLORCHANGE;
					break;

				case 2:
					FileBuffer[iDecValDialogOffset + k] = (char) (iDecValDialogValue & 0xff);
					FileBuffer[iDecValDialogOffset + k+1] = (char) ((iDecValDialogValue & 0xff00) >> 8);
					vChanges[iDecValDialogOffset + k] = COLORCHANGE;
					vChanges[iDecValDialogOffset + k+1] = COLORCHANGE;
					break;

				case 4:
					FileBuffer[iDecValDialogOffset + k  ] = (char) (iDecValDialogValue & 0xff);
					FileBuffer[iDecValDialogOffset + k+1] = (char) ((iDecValDialogValue & 0xff00) >> 8);
					FileBuffer[iDecValDialogOffset + k+2] = (char) ((iDecValDialogValue & 0xff0000) >> 16);
					FileBuffer[iDecValDialogOffset + k+3] = (char) ((iDecValDialogValue & 0xff000000) >> 24);
					vChanges[iDecValDialogOffset + k] = COLORCHANGE;
					vChanges[iDecValDialogOffset + k+1] = COLORCHANGE;
					vChanges[iDecValDialogOffset + k+2] = COLORCHANGE;
					vChanges[iDecValDialogOffset + k+3] = COLORCHANGE;
					break;
				}
			}
			else
			{
				switch (iDecValDialogSize)
				{
				case 1:
					FileBuffer[iDecValDialogOffset + k] = iDecValDialogValue;
					vChanges[iDecValDialogOffset + k] = COLORCHANGE;
					break;

				case 2:
					FileBuffer[iDecValDialogOffset + k+1] = (char) (iDecValDialogValue & 0xff);
					FileBuffer[iDecValDialogOffset + k] = (char) ((iDecValDialogValue & 0xff00) >> 8);
					vChanges[iDecValDialogOffset + k+1] = COLORCHANGE;
					vChanges[iDecValDialogOffset + k] = COLORCHANGE;
					break;

				case 4:
					FileBuffer[iDecValDialogOffset + k+3] = (char) (iDecValDialogValue & 0xff);
					FileBuffer[iDecValDialogOffset + k+2] = (char) ((iDecValDialogValue & 0xff00) >> 8);
					FileBuffer[iDecValDialogOffset + k+1] = (char) ((iDecValDialogValue & 0xff0000) >> 16);
					FileBuffer[iDecValDialogOffset + k+0] = (char) ((iDecValDialogValue & 0xff000000) >> 24);
					vChanges[iDecValDialogOffset + k+3] = COLORCHANGE;
					vChanges[iDecValDialogOffset + k+2] = COLORCHANGE;
					vChanges[iDecValDialogOffset + k+1] = COLORCHANGE;
					vChanges[iDecValDialogOffset + k] = COLORCHANGE;
					break;
				}
			}
			k += iDecValDialogSize;
		}
		SetCursor (LoadCursor (NULL, IDC_ARROW));
		iFileChanged = TRUE;
		bFilestatusChanged = TRUE;
		repaint ();
	}
	return 1;
}

int Translhextion::edit_append ()
{
	iAppendbytes = 1;
	iManipPos = iCurrentByte;
	if (DialogBox (hInstance, MAKEINTRESOURCE (IDD_APPENDDIALOG), *this, (DLGPROC) AppendDialogProc))
	{
		int i, oldupbound = FileBuffer.Length();
		SetCursor (LoadCursor (NULL, IDC_WAIT));
		if (FileBuffer.SetLength (FileBuffer.GetSize()+iAppendbytes) == FALSE)
		{
			MessageBoxA (*this, "Not enough memory for appending.", "Append error:", MB_OK | MB_ICONERROR);
			return FALSE;
		}
		int m = 0;
		for(m = 0;m<iAppendbytes;m++)
			vChanges.push_back(COLORCHANGE);
		FileBuffer.SetUpperBound(FileBuffer.Upper()+iAppendbytes);
		for (i=0; i<iAppendbytes; i++)
		{
			FileBuffer[oldupbound+i] = 0;
			vChanges[oldupbound+i] = COLORCHANGE;
		}
		SetCursor (LoadCursor (NULL, IDC_ARROW));
		iFileChanged = TRUE;
		bFilestatusChanged = TRUE;
		update_size_change ();
		repaint ();
	}
	return 1;
}

void Translhextion::insertfile()
{
	TCHAR cFileName[_MAX_PATH];
	TCHAR szTitleName[_MAX_FNAME + _MAX_EXT];
	cFileName[0] = '\0';
	OPENFILENAME ofn;
	ofn.lStructSize = sizeof (OPENFILENAME);
	ofn.hwndOwner = *this;
	ofn.hInstance = NULL;
	ofn.lpstrFilter = _T("All Files (*.*)\0*.*\0\0");
	ofn.lpstrCustomFilter = NULL;
	ofn.nMaxCustFilter = 0;
	ofn.nFilterIndex = 0;
	ofn.lpstrFile = cFileName;
	ofn.nMaxFile = _MAX_PATH;
	ofn.lpstrFileTitle = szTitleName;
	ofn.nMaxFileTitle = _MAX_FNAME + _MAX_EXT;
	ofn.lpstrInitialDir = NULL;
	ofn.lpstrTitle = _T("Open File to Insert");
	ofn.Flags = OFN_HIDEREADONLY | OFN_CREATEPROMPT | OFN_FILEMUSTEXIST;
	ofn.nFileOffset = 0;
	ofn.nFileExtension = 0;
	ofn.lpstrDefExt = NULL;
	ofn.lCustData = 0L;
	ofn.lpfnHook = NULL;
	ofn.lpTemplateName = NULL;
	if (GetOpenFileName (&ofn))
	{
		SetCursor( LoadCursor( NULL, IDC_WAIT ) );
		int fhandle;
		if((fhandle=_topen(cFileName,_O_RDONLY|_O_BINARY))!=-1)
		{
			int inslen;
			if((inslen=_filelength (fhandle))!= -1)
			{
				if(inslen){
					unsigned char* insbuf=new unsigned char[inslen];
					if(insbuf!=NULL){
						if (_read (fhandle, insbuf, inslen)!=-1)
						{
							if(!FileBuffer.InsertExpandOn(iCurrentByte,insbuf,0,inslen))
							{
								SetCursor( LoadCursor( NULL, IDC_ARROW ) );
								MessageBoxA(*this,"Could not insert data","Insert file error:",MB_OK | MB_ICONERROR);
							}
							else
							{
								long m = iCurrentByte;
								for(m = m;m<iCurrentByte + inslen;m++)
									//vChanges.insert(COLORCHANGE,m);
									vChanges.insert(vChanges.begin()+m,COLORCHANGE);
								iFileChanged = true; bFilestatusChanged = true; 
									SetCursor( LoadCursor( NULL, IDC_ARROW ) );repaint();
							}
						}
						else 
						{
								SetCursor( LoadCursor( NULL, IDC_ARROW ) );
							MessageBoxA(*this,"Could not read data from file","Insert file error:",MB_OK | MB_ICONERROR);
						}
						delete []insbuf;
					}
					else 
					{
							SetCursor( LoadCursor( NULL, IDC_ARROW ) );
						MessageBoxA(*this,"Not enough memory to read data from file","Insert file error:",MB_OK | MB_ICONERROR);
					}
				}
			}
			else MessageBoxA(*this,"Error checking file size.","Insert file error:",MB_OK | MB_ICONERROR);
			{
					SetCursor( LoadCursor( NULL, IDC_ARROW ) );
				_close (fhandle);
			}
		}
		else MessageBoxA(*this,"Error opening file.","Insert file error:",MB_OK | MB_ICONERROR);
		{
			SetCursor( LoadCursor( NULL, IDC_ARROW ) );
		}
	}
}

int find_bytes_relatively (char* ps, int ls, std::vector<relation>& offsets, int findstringlength, int mode)
{

	int start, inc, end;
	int match = 0;
	if (mode == 1)
	{
		start = 0;
		inc = 1;
		end = ls - findstringlength + 1;
	}
	else
	{
		start = ls - findstringlength;
		inc = -1;
		end = 1;
	}
	for (; mode * start < end; start += inc)
	{
		int k = 0;
		match = 0;
		for(k = 0;k<(int)offsets.size();k++)
		{
			iProgressPos++;
			if(progress1 != NULL && iProgressPos % iIncrementStep == 0)
			{
				StepProgress(progress1);
			}
			if(offsets[k].op == "=" && (ps[start + offsets[k].related] - ps[start + offsets[k].relate]) == offsets[k].offset)
			{
				match++;
			}
			else if(offsets[k].op == "<" && 
				(ps[start + offsets[k].relate] < ps[start + offsets[k].related] - offsets[k].offset
				|| ps[start + offsets[k].relate] > ps[start + offsets[k].related] + (25 - offsets[k].offset)))
			{
				match++;
			}
			else
			{
				break;
			}
		}
		if (match == offsets.size())
			return start;
	}
	return -1;
}

_tstring Translhextion::create_tablefind_string(_tstring x)
{
	std::vector<_tstring> phrase;
	int m = 0;
	FileVector<unsigned char> bcphrase;
	phrase.push_back(x);
	if(bOptimizeBytes)
	{
		bool oldbmark = bByteMark;
		bByteMark = false;
		table.descript(phrase);
		bByteMark = oldbmark;
	}
	else
	{
		bool oldbmark = bByteMark;
		bByteMark = true;
		table.descript(phrase);
		bByteMark = oldbmark;
	}
	table.detranslate(phrase);
	x = L"";
	for(m = 0;m<(int)phrase.size();m++)
	{
		x += char_hex(phrase[m]);
	}
	bcphrase.SetLength(phrase.size());
	bcphrase.SetUpperBound(phrase.size()-1);
	for(m =0;m<(int)phrase.size();m++)
		bcphrase[m] = char_hex(phrase[m]);
	int buflen = byte_to_bytecode_destinationlength((char*)&bcphrase[0], phrase.size() );
	TCHAR* cBuf = new TCHAR[buflen];
	translate_bytes_to_bytecode( cBuf, &bcphrase[0], phrase.size() );
	return (_tstring) cBuf;
}

int Translhextion::find ()
{
	if (filename.IsEmpty())
		return 0;

	//if( bSelected )
	//{
	//	int sel_start, select_len;
	//	if( iEndOfSelection < iStartOfSelection )
	//	{
	//		sel_start = iEndOfSelection;
	//		select_len = iStartOfSelection - iEndOfSelection + 1;
	//	}
	//	else
	//	{
	//		sel_start = iStartOfSelection;
	//		select_len = iEndOfSelection - iStartOfSelection + 1;
	//	}
	//	iFindDialogBufLength = byte_to_bytecode_destinationlength( (char*) &FileBuffer[sel_start], select_len );
	//	iFindDialogLastLength = iFindDialogBufLength;
	//	if( pcFindDialogBuffer != NULL )
	//		delete [] pcFindDialogBuffer;
	//	pcFindDialogBuffer = new TCHAR[iFindDialogBufLength];
	//	translate_bytes_to_bytecode( pcFindDialogBuffer, &FileBuffer[sel_start], select_len );
	//}
	CFindStringDlg dlg(*this);

	// show Find dialog
	if(dlg.DoModal()==IDOK)
	{
		if (src_helper.GetSearchSize()>0)
		{
			int i;

			SetCursor (LoadCursor (NULL, IDC_WAIT));
			if (iFindDialogDirection == 1)
			{
				i = find_bytes (&(FileBuffer[iCurrentByte + 1]), FileBuffer.Length() - iCurrentByte - 1,
					src_helper.GetSearchData(), src_helper.GetSearchSize(),
					1,
					src_helper.GetSearchMethod());
				if (i != -1)
					iCurrentByte += i + 1;
			}
			else
			{
				i = find_bytes(&(FileBuffer[0]),
					min( iCurrentByte + (src_helper.GetSearchSize() - 1), FileBuffer.Length() ),
					src_helper.GetSearchData(), src_helper.GetSearchSize(),
					-1,
					src_helper.GetSearchMethod());
				if (i != -1)
					iCurrentByte = i;
			}
			SetCursor (LoadCursor (NULL, IDC_ARROW));

			if (i != -1)
			{
				bSelected = TRUE;
				iStartOfSelection = iCurrentByte;
				iEndOfSelection = iCurrentByte + src_helper.GetSearchSize() - 1;
				adjust_view_for_selection();

				repaint();
			}
			else MessageBox (LoadString(IDS_NOTICE_STR_NOT_FOUND), LoadString(IDS_TITLE_NOTICE), MB_OK | MB_ICONINFORMATION);
			iFindDialogLastLength = src_helper.GetSearchSize();

			bLastSearchType = 0;
		}
	}

	return 1;
}

int Translhextion::find_hex ()
{
	//if (filename[0] == '\0')
	//	return 0;

	//if( bSelected )
	//{
	//	int sel_start, select_len;
	//	if( iEndOfSelection < iStartOfSelection )
	//	{
	//		sel_start = iEndOfSelection;
	//		select_len = iStartOfSelection - iEndOfSelection + 1;
	//	}
	//	else
	//	{
	//		sel_start = iStartOfSelection;
	//		select_len = iEndOfSelection - iStartOfSelection + 1;
	//	}
	//	iFindDialogBufLength = byte_to_bytecode_destinationlength( (char*) &FileBuffer[sel_start], select_len );
	//	iFindDialogLastLength = iFindDialogBufLength;
	//	if( pcFindDialogBuffer != NULL )
	//		delete [] pcFindDialogBuffer;
	//	pcFindDialogBuffer = new TCHAR[iFindDialogBufLength];
	//	translate_bytes_to_bytecode( pcFindDialogBuffer, &FileBuffer[sel_start], select_len );
	//}

	// show Find dialog
	CFindHexDlg dlg(*this);

	if(dlg.DoModal()==IDOK)
	{
		if (src_helper.GetSearchData()>0)
		{
			int i;

			SetCursor (LoadCursor (NULL, IDC_WAIT));
			if (iFindDialogDirection == 1)
			{
				i = find_bytes (&(FileBuffer[iCurrentByte + 1]), FileBuffer.Length() - iCurrentByte - 1,
					src_helper.GetSearchData() /*pcFindstring*/, src_helper.GetSearchSize() /*iDestinationLength*/, 1, src_helper.GetSearchMethod() /*cmp*/);
				if (i != -1)
					iCurrentByte += i + 1;
			}
			else
			{
				i = find_bytes(&(FileBuffer[0]),
					min( iCurrentByte + (src_helper.GetSearchSize() /*iDestinationLength*/ - 1), FileBuffer.Length() ),
					src_helper.GetSearchData() /*pcFindstring*/, src_helper.GetSearchSize() /*iDestinationLength*/, -1, src_helper.GetSearchMethod() /*cmp*/);
				if (i != -1)
					iCurrentByte = i;
			}
			SetCursor (LoadCursor (NULL, IDC_ARROW));

			if (i != -1)
			{
				bSelected = TRUE;
				iStartOfSelection = iCurrentByte;
				iEndOfSelection = iCurrentByte + src_helper.GetSearchSize() /*iDestinationLength*/ - 1;
				adjust_view_for_selection();

				repaint();
			}
			else
				MessageBox (LoadString(IDS_NOTICE_STR_NOT_FOUND), LoadString(IDS_TITLE_NOTICE), MB_OK | MB_ICONINFORMATION);
			iFindDialogLastLength = src_helper.GetSearchSize()/*iLengthgthOfSource*/;

			bLastSearchType = 0;
		}
	}
	return 1;
}

int Translhextion::find_with_table()
{
	if (filename.IsEmpty())
		return 0;

	int iLengthgthOfSource = DialogBox (hInstance, MAKEINTRESOURCE (IDD_TABLEFINDDIALOG), *this, (DLGPROC) FindWithTableDialogProc);
	if (iLengthgthOfSource != 0)
	{
		sLastTableSearch = (_tstring) src_helper.GetSearchString() /*pcFindDialogBuffer*/;
		_tstring temp = create_tablefind_string(sLastTableSearch);
		//strcpy(pcFindDialogBuffer,temp.c_str());
		iFindDialogLastLength = iLengthgthOfSource;
		bLastSearchType = 0;
		if(iFindDialogDirection == -1)
		{
			bFirstSearch = true;
			findprev();
			bFirstSearch = false;
		}
		else if(iFindDialogDirection == 1)
		{
			bFirstSearch = true;
			findnext();		
			bFirstSearch = false;
		}
	}
	return 1;
}


int Translhextion::findnext()
{
	if( src_helper.GetSearchData() /*pcFindDialogBuffer != NULL*/ )
	{
		//u8* pcFindstring;
		//int iLengthgthOfSource = strlen( pcFindDialogBuffer );
		//int iDestinationLength = bytecode_translate( &pcFindstring, pcFindDialogBuffer, iLengthgthOfSource, iCharacterSet, iBinaryMode );
		//if( iDestinationLength > 0 )
		//{
		//	int i;
		//	int (*cmp) (u8*);

		//	if( iFindDialogMatchCase == BST_CHECKED )
		//		cmp = literal_u8;
		//	else
		//		cmp = charcase_u8;

			SetCursor( LoadCursor( NULL, IDC_WAIT ) );

			int i = find_bytes(&(FileBuffer[iCurrentByte + 1]), FileBuffer.Length () - iCurrentByte - 1,
				src_helper.GetSearchData() /*pcFindstring*/, src_helper.GetSearchSize() /*iDestinationLength*/, 1, src_helper.GetSearchMethod() /*cmp*/ );
			if( i != -1 )
				iCurrentByte += i + 1;

			SetCursor( LoadCursor( NULL, IDC_ARROW ) );
			if( i != -1 )
			{
				bSelected = TRUE;
				iStartOfSelection = iCurrentByte;
				iEndOfSelection = iCurrentByte + src_helper.GetSearchSize() /*iDestinationLength*/ - 1;
				adjust_view_for_selection();
				repaint();
			}
			else
			{
				if(bFirstSearch)
				{
					MessageBox (LoadString(IDS_NOTICE_STR_NOT_FOUND), LoadString(IDS_TITLE_NOTICE), MB_OK | MB_ICONINFORMATION);
					bFirstSearch = false;
				}
				else
				{
					MessageBox(LoadString(IDS_NOTICE_NO_MORE_MATCHES), LoadString(IDS_TITLE_NOTICE), MB_OK | MB_ICONINFORMATION );
				}
			}
			//delete [] pcFindstring;
	//	}
	//	else
	//		MessageBoxA( *this, "Findstring is zero bytes long.", "Find next error:", MB_OK | MB_ICONERROR );
	//}
	//else
	//{
	//	MessageBoxA( *this, "String to find not specified.", "Find next error:", MB_OK | MB_ICONERROR );
	}

	return 0;
}

int Translhextion::findprev()
{
	if( src_helper.GetSearchData() /*pcFindDialogBuffer != NULL*/ )
	{
	//	u8* pcFindstring;
	//	int iLengthgthOfSource = /*strlen( pcFindDialogBuffer )*/;
	//	int iDestinationLength = bytecode_translate( &pcFindstring, pcFindDialogBuffer, iLengthgthOfSource, iCharacterSet, iBinaryMode );
	//	if( iDestinationLength > 0 )
	//	{
			int i;
	//		int (*cmp) (u8*);

	//		if( iFindDialogMatchCase == BST_CHECKED ) cmp = literal_u8;
	//		else cmp = charcase_u8;

			SetCursor( LoadCursor( NULL, IDC_WAIT ) );

			i = find_bytes(&(FileBuffer[0]),
				min( iCurrentByte + (src_helper.GetSearchSize()/*iDestinationLength*/ - 1), FileBuffer.Length() ),
				src_helper.GetSearchData()/*pcFindstring*/, src_helper.GetSearchSize()/*iDestinationLength*/, -1, src_helper.GetSearchMethod() /*cmp*/ );
			if (i != -1)
				iCurrentByte = i;

			SetCursor( LoadCursor( NULL, IDC_ARROW ) );
			if( i != -1 )
			{
				bSelected = TRUE;
				iStartOfSelection = iCurrentByte;
				iEndOfSelection = iCurrentByte + src_helper.GetSearchSize() - 1;
				adjust_view_for_selection();
				repaint();
			}
			else
			{
				if(bFirstSearch)
				{
					MessageBox (LoadString(IDS_NOTICE_STR_NOT_FOUND), LoadString(IDS_TITLE_NOTICE), MB_OK | MB_ICONINFORMATION);
					bFirstSearch = false;
				}
				else MessageBox(LoadString(IDS_NOTICE_NO_MORE_MATCHES), LoadString(IDS_TITLE_NOTICE), MB_OK | MB_ICONINFORMATION );
			}
	//		delete [] pcFindstring;
	//	}
	//	else
	//		MessageBoxA( *this, "Findstring is zero bytes long.", "Find previous error:", MB_OK | MB_ICONERROR );
	}
	//else
	//{
	//	MessageBoxA( *this, "String to find not specified.", "Find previous error:", MB_OK | MB_ICONERROR );
	//}
	return 0;
}

int Translhextion::findnext_relative()
{
	if( src_helper.vRelativeOffsets.size() > 0 )
	{
		SetCursor (LoadCursor (NULL, IDC_WAIT));
		int i = find_bytes_relatively ((char*) &(FileBuffer[iCurrentByte + 1]), FileBuffer.Length() - iCurrentByte - 1, src_helper.vRelativeOffsets,sRelSearchString.length(), 1);
		if (i != -1)
			iCurrentByte += i + 1;
		SetCursor (LoadCursor (NULL, IDC_ARROW));
		if (i != -1)
		{
			bSelected = TRUE;
			iStartOfSelection = iCurrentByte;
			iEndOfSelection = iCurrentByte + sRelSearchString.length() - 1;
			adjust_view_for_selection();
			repaint();
		}
		else
		{
			if(!bFileRelativeResults)
			{
				MessageBox (LoadString(IDS_NOTICE_NO_MORE_RMATCHES), LoadString(IDS_TITLE_NOTICE), MB_OK | MB_ICONINFORMATION);
			}
			else
			{
				bRelativeSearchDone = true;
			}
		}
	}
	else
	{
		if(bFileRelativeResults)
		{
			bRelativeSearchDone = true;
		}
		else
		{
			MessageBoxA( *this, "String to find not specified.", "Find next relatively error:", MB_OK | MB_ICONERROR );
		}
	}
	return 0;
}

int Translhextion::findprev_relative()
{
	if( src_helper.vRelativeOffsets.size() > 0 )
	{
		SetCursor (LoadCursor (NULL, IDC_WAIT));
		int i = find_bytes_relatively( (char*) &(FileBuffer[0]),
			min( iCurrentByte + (iFindDialogLastLength - 1), FileBuffer.Length() ),
			src_helper.vRelativeOffsets,sRelSearchString.length(), -1);
		if (i != -1)
			iCurrentByte = i;
		SetCursor (LoadCursor (NULL, IDC_ARROW));
		if (i != -1)
		{
			bSelected = TRUE;
			iStartOfSelection = iCurrentByte;
			iEndOfSelection = iCurrentByte + sRelSearchString.length() - 1;
			adjust_view_for_selection();
			repaint();
		}
		else
		{
			if(!bFileRelativeResults)
			{
				MessageBox (LoadString(IDS_NOTICE_NO_MORE_RMATCHES), LoadString(IDS_TITLE_NOTICE), MB_OK | MB_ICONINFORMATION);
			}
			else
			{
				bRelativeSearchDone = true;
			}
		}
	}
	else
	{
		if(bFileRelativeResults)
		{
			bRelativeSearchDone = true;
		}
		else
		{
			MessageBoxA( *this, "String to find not specified.", "Find previous relatively:", MB_OK | MB_ICONERROR );
		}
	}
	return 0;
}

void Translhextion::replace()
{
	if( bSelected )
	{
		int sel_start, select_len;
		if( iEndOfSelection < iStartOfSelection )
		{
			sel_start = iEndOfSelection;
			select_len = iStartOfSelection - iEndOfSelection + 1;
		}
		else
		{
			sel_start = iStartOfSelection;
			select_len = iEndOfSelection - iStartOfSelection + 1;
		}

		if( translate_binary_to_text( strToReplaceData, (char*) &FileBuffer[sel_start], select_len ) )
		{
		}
		else
		{
			MessageBox(LoadString(IDS_NOTICE_SEL_CANT_REPLACE), LoadString(IDS_TITLE_NOTICE), MB_OK | MB_ICONINFORMATION);
			return;
		}
	}

	bDontMarkCurrentPos = TRUE;
	if( DialogBox( hInstance, MAKEINTRESOURCE(IDD_REPLACEDIALOG), *this, (DLGPROC) ReplaceDialogProc ) )
	{
		if(bReplaceFileChange)
		{
			iFileChanged = true;
			bReplaceFileChange = false;
		}
	}
	bDontMarkCurrentPos = FALSE;
}

void Translhextion::replace_with_table()
{
	bDontMarkCurrentPos = TRUE;
	if( DialogBox( hInstance, MAKEINTRESOURCE(IDD_TABLEREPLACEDIALOG), *this, (DLGPROC) ReplaceWithTableDialogProc ) )
	{
		if(bReplaceFileChange)
		{
			iFileChanged = true;
			bReplaceFileChange = false;
		}
	}
	bDontMarkCurrentPos = FALSE;
}


relativescandata Translhextion::guess_table_values(long start)
{
	int i = 0;
	int cap = -1;
	int low = -1;
	int num = -1;
	RelativeOffsets result;
	result.bA = false;
	result.ba = false;
	result.bn = false;
	_tstring sResult;
	relativescandata result2;
	result2.start = start;
	result2.end = start + sRelSearchString.length();
	result2.search = sRelSearchString;
	for(i = 0;i<(int)sRelSearchString.length();i++)
	{
		if(sRelSearchString[i] >= 'A' && sRelSearchString[i] <= 'Z')
		{	
			cap = i;
			result.A = FileBuffer[start + cap] - (sRelSearchString[i] - 'A');
			result.bA = true;
			break;
		}
	}
	for(i = 0;i<(int)sRelSearchString.length();i++)
	{
		if(sRelSearchString[i] >= '1' && sRelSearchString[i] <= '9')
		{	
			num = i;
			result.n = FileBuffer[start + num] - (sRelSearchString[i] - '1');
			result.bn = true;
			break;
		}
	}
	for(i = 0;i<(int)sRelSearchString.length();i++)
	{
		if(sRelSearchString[i] >= 'a' && sRelSearchString[i] <= 'z')
		{	
			low = i;
			result.a = FileBuffer[start + low] - (sRelSearchString[i] - 'a');
			result.ba = true;
			break;
		}
	}
	sResult += L"A=";
	if(result.bA)
	{
		result2.A = hex_char(result.A);
		sResult += hex_char(result.A) + L" ";
	}
	else
	{
		result2.A = L"??";
		sResult += L"?? ";
	}
	sResult += L"a=";
	if(result.ba)
	{
		result2.a = hex_char(result.a);
		sResult += hex_char(result.a) + L" ";
	}
	else
	{
		result2.a = L"??";
		sResult += L"?? ";
	}
	sResult += L"1=";
	if(result.bn)
	{
		result2.n = hex_char(result.n);
		sResult += hex_char(result.n);
	}
	else
	{
		result2.n = L"??";
		sResult += L"??";
	}
	result2.listitem = sResult;
	return result2;
}


int Translhextion::search_relative()
{
	if (filename.IsEmpty())
		return 0;
	int i = 0;
	int iLengthgthOfSource = DialogBox (hInstance, MAKEINTRESOURCE (IDD_SEARCHRELATIVEDIALOG), *this, (DLGPROC) SearchRelativeDialogProc);
	if (iLengthgthOfSource > 1)
	{
		src_helper.CreateRelativeSearchString(src_helper.GetSearchRel());
		
		if (iFindDialogDirection == 1)
		{
			i = find_bytes_relatively ((char*) &(FileBuffer[iCurrentByte + 1]), FileBuffer.Length() - iCurrentByte - 1, src_helper.vRelativeOffsets,sRelSearchString.length(), 1);
			if (i != -1)
				iCurrentByte += i + 1;
		}
		
		else
		{
			i = find_bytes_relatively( (char*) &(FileBuffer[0]),
				min( iCurrentByte + (iLengthgthOfSource - 1), FileBuffer.Length() ),
				src_helper.vRelativeOffsets,sRelSearchString.length(), -1);
			if (i != -1)
				iCurrentByte = i;
		}
		SetCursor (LoadCursor (NULL, IDC_ARROW));
		if (i != -1)
		{
			bSelected = TRUE;
			iStartOfSelection = iCurrentByte;
			
			iEndOfSelection = iCurrentByte + sRelSearchString.length() - 1;
			adjust_view_for_selection();
			repaint();
		}
		else
		{
			MessageBox (LoadString(IDS_NOTICE_RSEARCH_NO_FOUND), LoadString(IDS_TITLE_NOTICE), MB_OK | MB_ICONINFORMATION);
		}
		iFindDialogLastLength = iLengthgthOfSource;
		bLastSearchType = 1;
		
	}
	else if(iLengthgthOfSource == 1)
	{
		MessageBox(LoadString(IDS_NOTICE_RSEARC_MIN_LEN),LoadString(IDS_TITLE_NOTICE),MB_OK | MB_ICONINFORMATION);
	}
	else if(iLengthgthOfSource == -5)
	{
		;
	}
	else
	{
		
		MessageBoxA( *this, "String to find not specified.", "Search Relative error:", MB_OK | MB_ICONERROR );
	}
	return 1;
}

long Translhextion::scan_relative_helper(int iLengthgthOfSource)
{
	
	int i = 0;
	if (iFindDialogDirection == 1)
	{
		if(progress1 != NULL)
		{
			SetProgressRange(progress1,iCurrentByte - 1,FileBuffer.Length());
			if(FileBuffer.Length() >= 10000)
			{
				iIncrementStep = FileBuffer.Length() / 1000;
			}
			else if(FileBuffer.Length() >= 1000)//this could be better
			{
				iIncrementStep = FileBuffer.Length() / 100;
			}
			else if(FileBuffer.Length() >= 100)
			{
				iIncrementStep = FileBuffer.Length() / 10;
			}
			else
			{
				iIncrementStep = 2; 
			}
			SetProgressStep(progress1,iIncrementStep);
		}
		i = find_bytes_relatively ((char*) &(FileBuffer[iCurrentByte + 1]), FileBuffer.Length() - iCurrentByte - 1, src_helper.vRelativeOffsets,sRelSearchString.length(),1);
		if (i != -1)
			iCurrentByte += i + 1;
	}
	else
	{
		if(progress1 != NULL)
		{
			SetProgressRange(progress1,0,min( iCurrentByte + (iLengthgthOfSource - 1), FileBuffer.Length()));
			if(FileBuffer.Length() >= 10000)
			{
				iIncrementStep = FileBuffer.Length() / 1000;
			}
			else if(FileBuffer.Length() >= 1000)//this could be better
			{
				iIncrementStep = FileBuffer.Length() / 100;
			}
			else if(FileBuffer.Length() >= 100)
			{
				iIncrementStep = FileBuffer.Length() / 10;
			}
			else
			{
				iIncrementStep = 2; 
			}
			SetProgressStep(progress1,iIncrementStep);
		}
		i = find_bytes_relatively( (char*) &(FileBuffer[0]),
			min( iCurrentByte + (iLengthgthOfSource - 1), FileBuffer.Length() ),
			src_helper.vRelativeOffsets,sRelSearchString.length(), -1);
		if (i != -1)
			iCurrentByte = i;
	}
	if (i != -1)
	{
		bSelected = TRUE;
		iStartOfSelection = iCurrentByte;
		iEndOfSelection = iCurrentByte + sRelSearchString.length() - 1;
		mainwindow.adjust_view_for_selection();
		mainwindow.repaint();
	}
	else
	{
		bRelativeSearchDone = true;
	}
	bLastSearchType = 1;
	return iCurrentByte;
}

void Translhextion::save_relative_results(fstream& fs)
{
	//GString cBuf;
	//string output;
	//int index = 0;
	//for(index = 0; index < (int)vScanData.size();index++)
	//{
	//	if(iOffsetMode == LOROM)
	//		cBuf.Format(_T("%d=0x%X\t"), vScanData[index].start, toLOROM(vScanData[index].start));
	//	else if(iOffsetMode == HIROM)
	//		cBuf.Format(_T("%d=0x%X\t", vScanData[index].start, toHIROM(vScanData[index].start));
	//	else
	//		cBuf.Format(_T("%d=0x%X\t", vScanData[index].start, vScanData[index].start);
	//	//fs << "Offset: \t\t" << (_tstring) cBuf << endl;
	//	int k = 0;
	//	for(k = 0;k<(int)sRelSearchString.length();k++)
	//	{
	//		output += hex_char(FileBuffer[vScanData[index].start + k]) + " ";
	//	}
	//	fs << "Hex Data: \t" << output << endl;
	//	output = "";
	//	for(k = 0;k<(int)sRelSearchString.length();k++)
	//	{
	//		output += FileBuffer[vScanData[index].start + k];
	//	}
	//	fs << "ASCII Data: \t" << output << endl;
	//	fs << "Relative Offsets: \t" << vScanData[index].listitem << endl << endl;
	//	output = "";
	//}
}

int Translhextion::scan_relative()
{
	CScanRelativeDlg dlg(*this);
	dlg.DoModal();

	//if (filename[0] == '\0')
	//	return 0;
	//int i = 0;
	//int iLengthgthOfSource = DialogBox (hInstance, MAKEINTRESOURCE (IDD_SCANRELATIVEDIALOG), *this, (DLGPROC) ScanRelativeDialogProc);
	//if (iLengthgthOfSource != 0)
	//{
	//	
	//}
	return 1;
}


int Translhextion::value_scan_relative()
{
	//if (filename[0] == '\0')
	//	return 0;
	//int i = 0;
	//int iLengthgthOfSource = DialogBox (hInstance, MAKEINTRESOURCE (IDD_VALSCANRELATIVEDIALOG), *this, (DLGPROC) ValScanRelativeDialogProc);
	//if (iLengthgthOfSource != 0)
	//{
	//	
	//}
	CRelativeValueDlg dlg(*this);
	dlg.DoModal();

	return 1;
}


//BOOKMARKS

int Translhextion::add_bookmark ()
{
	if (FileBuffer.Length()<=0)
	{
		MessageBoxA (*this, "Can not set bookmark in empty file.", "Add bookmark error:", MB_OK | MB_ICONERROR);
		return 0;
	}
	if (iBookmarkCount<iBookmarkMax)
	{
		iBookmarkOffset = iCurrentByte;
		pcBookmarkTxt[0]=0;
		if (DialogBox (hInstance, MAKEINTRESOURCE (IDD_ADDBMK_DIALOG), *this, (DLGPROC) AddBookmarkDialogProc))
		{
			if (iBookmarkOffset>=0 && iBookmarkOffset<=FileBuffer.Length())
			{
				if(iOffsetMode == LOROM)
					iBookmarkOffset = toLOROM(iCurrentByte);
				else if(iOffsetMode == HIROM)
					iBookmarkOffset = toHIROM(iCurrentByte);
				else
					iBookmarkOffset = iCurrentByte;
				
				int i;
				for( i = 0; i < iBookmarkCount; i++ )
				{
					if( pbmkList[ i ].offset == iBookmarkOffset )
					{
						MessageBoxA (*this, "There already is a bookmark on that position.", "Add bookmark error:", MB_OK | MB_ICONERROR);
						return 0;
					}
				}
				
				if(sLoadedTable != _T(""))
				{
					_tstring totable;
					TCHAR cBuf[512];
					sprintf (cBuf, _T("%X"), iBookmarkOffset);
					totable = _T("(") + (_tstring) cBuf + _T("h)") + (_tstring)pcBookmarkTxt;
					mainwindow.table.vTableFileLeft.push_back(totable);
					mainwindow.table.vTableFileRight.push_back(_T(""));
					fstream fs;
					fs.open(sLoadedTable.c_str(),ios::out);
					
					save_table_file(fs);
					fs.close();
				}

				pbmkList[iBookmarkCount].offset = iBookmarkOffset;
				if (strlen(pcBookmarkTxt)>0)
				{
					pbmkList[iBookmarkCount].name = new TCHAR[strlen(pcBookmarkTxt)+1];
					strcpy (pbmkList[iBookmarkCount].name, pcBookmarkTxt);
				}
				else
					pbmkList[iBookmarkCount].name = NULL;
				iBookmarkCount++;
				repaint();
			}
			else
			{
				MessageBoxA (*this, "Can not set bookmark at that position.", "Add bookmark error:", MB_OK | MB_ICONERROR);
				return 0;
			}
		}
	}
	else
	{
		MessageBox (LoadString(IDS_NOTICE_BOOKMARKS_MAX), LoadString(IDS_TITLE_NOTICE), MB_OK | MB_ICONINFORMATION);
	}
	return 0;
}


int Translhextion::remove_bookmark ()
{
	//if (iBookmarkCount==0)
	//{
	//	MessageBoxA (*this, "No bookmarks to remove.", "Remove bookmark error:", MB_OK | MB_ICONERROR);
	//	return 0;
	//}
	//pbmkRemove = pbmkList;
	//iRemBookmark = iBookmarkCount;
	//if (DialogBox (hInstance, MAKEINTRESOURCE (IDD_REMOVEBMK_DIALOG), *this, (DLGPROC) RemoveBookmarkDialogProc))
	//{
	//	if(sLoadedTable != "")
	//	{
	//		_tstring totable;
	//		TCHAR cBuf[512];
	//		if(iOffsetMode == LOROM)
	//			sprintf (cBuf,_T("%X"),toLOROM(pbmkList[iRemBookmark].offset));
	//		else if(iOffsetMode == HIROM)
	//			sprintf (cBuf,_T("%X"),toHIROM(pbmkList[iRemBookmark].offset));
	//		else
	//			sprintf (cBuf,_T("%X"),pbmkList[iRemBookmark].offset);
	//		totable = _T("(") + (_tstring) cBuf;
	//		int k = 0;
	//		for(k = 0;k < (int)vTableFileLeft.size();k++)
	//		{
	//			if(vTableFileLeft[k].substr(0,totable.length()) == totable)
	//			{
	//				//vTableFileLeft.remove(k);
	//				vTableFileLeft.erase(vTableFileLeft.begin()+k);
	//				//vTableFileRight.remove(k);
	//				vTableFileRight.erase(vTableFileRight.begin()+k);
	//				break;
	//			}
	//		}
	//		fstream fs;
	//		fs.open(sLoadedTable.c_str(),ios::out);
	//		save_table_file(fs);
	//		fs.close();
	//	}
	//	if (pbmkList[iRemBookmark].name != NULL)
	//		delete [] (pbmkList[iRemBookmark].name);
	//	int i;
	//	for (i=iRemBookmark; i<iBookmarkCount-1; i++)
	//		pbmkList[i] = pbmkList[i+1];
	//	iBookmarkCount--;
	//	repaint();
	//}
	return 1;
}


int Translhextion::clear_all_bookmark ()
{
	//if(bReadingTable || MessageBoxA( *this, "Are you sure you want to clear all bookmarks?", LoadString(IDS_TITLE_NOTICE), MB_YESNO | MB_ICONQUESTION ) == IDYES )
	//{
	//	int i;
	//	for (i=0; i<iBookmarkCount; i++)
	//		if (pbmkList[i].name != NULL)
	//			delete [] (pbmkList[i].name);
	//	iBookmarkCount = 0;
	//	if(!bReadingTable && sLoadedTable != L"")
	//	{
	//		int k = 0;
	//		for(k = 0;k < (int)vTableFileLeft.size();k++)
	//		{
	//			if(vTableFileLeft[k].substr(0,1) == L"(")
	//			{
	//				//vTableFileLeft.remove(k);
	//				vTableFileLeft.erase(vTableFileLeft.begin()+k);
	//				//vTableFileRight.remove(k);
	//				vTableFileRight.erase(vTableFileRight.begin()+k);
	//				k--;
	//			}
	//		}
	//		fstream fs;
	//		fs.open(sLoadedTable.c_str(),ios::out);
	//		save_table_file(fs);
	//		fs.close();
	//	}
	//	return 1;
	//}
	return 1;
}


int Translhextion::goto_bookmark( int cmd )
{
	long offset = 0;
	if(iOffsetMode == LOROM)
		offset = fromLOROM(pbmkList[ cmd - IDM_BOOKMARK1 ].offset);
	else if(iOffsetMode == HIROM)
		offset = fromHIROM(pbmkList[ cmd - IDM_BOOKMARK1 ].offset);
	else
		offset = pbmkList[ cmd - IDM_BOOKMARK1 ].offset;
	if( offset >= 0 && offset <= FileBuffer.Length() )
	{
		iCurrentByte = offset;
		update_size_change();
		update_vertical_scrollbar();
		repaint();
	}
	else
	{
		MessageBoxA (*this, "Bookmark points to invalid position.", "Go to bookmark error:", MB_OK | MB_ICONERROR);
	}
	return 0;
}

//SCRIPT

int Translhextion::open_table ()
{
	if (bTableLoaded)
	{
		if (MessageBox (LoadString(IDS_NOTICE_TABLE_DISCARD), LoadString(IDS_TITLE_NOTICE), MB_YESNO | MB_ICONQUESTION) == IDNO)
			return 0;
	}

	CFileDialog dlg;
	dlg.Create(*this,LoadString(IDS_FILTER_TABLE),LoadString(IDS_FILTER_TABLE_TITLE),OFN_HIDEREADONLY | OFN_CREATEPROMPT | OFN_FILEMUSTEXIST);

	//TCHAR cFileName[_MAX_PATH];
	//TCHAR szTitleName[_MAX_FNAME + _MAX_EXT];
	//cFileName[0] = '\0';
	//OPENFILENAME ofn;
	//ofn.lStructSize = sizeof (OPENFILENAME);
	//ofn.*thisOwner = *this;
	//ofn.hInstance = NULL;
	//ofn.lpstrFilter = LoadFileFilter(IDS_FILTER_TABLE) /*_T("Thingy Table Files (*.TBL)\0*.TBL\0\0")*/;
	//ofn.lpstrCustomFilter = NULL;
	//ofn.nMaxCustFilter = 0;
	//ofn.nFilterIndex = 0;
	//ofn.lpstrFile = cFileName;
	//ofn.nMaxFile = _MAX_PATH;
	//ofn.lpstrFileTitle = szTitleName;
	//ofn.nMaxFileTitle = _MAX_FNAME + _MAX_EXT;
	//ofn.lpstrInitialDir = NULL;
	//ofn.lpstrTitle = _T("Open Thingy Table File");
	//ofn.Flags = OFN_HIDEREADONLY | OFN_CREATEPROMPT | OFN_FILEMUSTEXIST;
	//ofn.nFileOffset = 0;
	//ofn.nFileExtension = 0;
	//ofn.lpstrDefExt = NULL;
	//ofn.lCustData = 0L;
	//ofn.lpfnHook = NULL;
	//ofn.lpTemplateName = NULL;
	if (dlg.DoModal()/*GetOpenFileName (&ofn)*/)
	{
		if (file_can_load (dlg.GetFileName()/*cFileName*/))
		{
			sFileName = dlg.GetFileName();
			if (wread_table_file(dlg.GetFileName()))
			{
				strcpy(filename2,sFileName.c_str());
				update_most_recent_table();
				SetCursor (LoadCursor (NULL, IDC_ARROW));
				if(iRealTable > 0)
				{
					if(bTableLoaded)
					{
						bTableActive = false;
						bThingyView = false;
						CheckDlgButton(hwndTBar,IDC_CHECK1,BST_UNCHECKED);
						CheckDlgButton(hwndTBar,IDC_CHECK2,BST_UNCHECKED);
						bTableLoaded = true;
						bTableActive = true;
						sLoadedTable = sFileName;
					}
					else
					{
						bTableLoaded = true;
						bTableActive = true;
						hwndTBar = CreateDialog(hInstance, MAKEINTRESOURCE (IDD_THINGYBAR),*this,ToolBarDialogProc);
						sLoadedTable = sFileName;
					}
					//another optimization problem as commented further above in this file
					GString message;
					message.Format(LoadString(IDS_NOTICE_TBL_TOKEN_CNT),iRealTable);
					MessageBox(message,LoadString(IDS_TITLE_NOTICE), MB_OK | MB_ICONINFORMATION);
				}
				else
				{
					if(bTableLoaded)
					{
						DestroyWindow(hwndTBar);
						bTableLoaded = false;
						bTableActive = false;
						bThingyView = false;
						sLoadedTable = _T("");
						//vTableFileLeft = vEmpty;
						//vTableFileRight = vEmpty;
					}
					MessageBox(LoadString(IDS_TBLERR_UNKNOWN_FORMAT),LoadString(IDS_TITLE_TABLE_ERROR), MB_OK | MB_ICONERROR);
				}

			}
			else
			{
				GString cBuf;
				cBuf.Format(LoadString(IDS_TBLERR_ERROR_CODE), errno, (LPCTSTR)dlg.GetFileName());
				MessageBox (cBuf, LoadString(IDS_TITLE_TABLE_ERROR), MB_OK | MB_ICONERROR);
				return FALSE;
			}
			
		}					
	}
	repaint();
	return 1;
}

int Translhextion::convert_table()
{
	//if (DialogBox (hInstance, MAKEINTRESOURCE (IDD_TABLECONVERTDIALOG), hwnd, (DLGPROC) TableConvertDialogProc))
	//{
	//	fstream fs;
	//	fs.open(sLoadedTable.c_str(),ios::in);
	//	if(!fs.fail())
	//	{
	//		wread_table_file(fs);
	//		fs.close();
	//		mainwindow.repaint();
	//		mainwindow.update_size_change();
	//		if(!(iRealTable > 0))
	//		{
	//			if(bTableLoaded)
	//			{
	//				DestroyWindow(hwndTBar);
	//				bTableLoaded = false;
	//				bTableActive = false;
	//				bThingyView = false;
	//				vTableFileLeft = vEmpty;
	//				vTableFileRight = vEmpty;
	//				sLoadedTable = "";
	//			}
	//			MessageBox(hwnd,"This file does not seem to be a table.  Investigate the problem or load another table.",LoadString(IDS_TITLE_TABLE_ERROR), MB_OK | MB_ICONERROR);
	//		}
	//	}
	//}
	return 1;
}

int Translhextion::script_dump ()
{
	//long numbytes = 0;
	//int difference = 0;
	//if (!bSelected)
	//{
	//	iCopyStartOffset = iCurrentByte;
	//	iCopyEndOffset = iCurrentByte;
	//}
	//else
	//{
	//	if (iEndOfSelection >= iStartOfSelection)
	//	{
	//		iCopyStartOffset = iStartOfSelection;
	//		iCopyEndOffset = iEndOfSelection;
	//	}
	//	else
	//	{
	//		iCopyStartOffset = iEndOfSelection;
	//		iCopyEndOffset = iStartOfSelection;
	//	}
	//}
	//if(iDumpEnd != 0)
	//{
	//	iCopyStartOffset = iDumpStart;
	//	iCopyEndOffset = iDumpEnd;
	//}

	//if (DialogBox (hInstance, MAKEINTRESOURCE (IDD_SCRIPTDUMPDIALOG), hwnd, (DLGPROC) ScriptDumpDialogProc) != FALSE)
	//{
	//	iStartOfSelection = iCopyStartOffset;
	//	iEndOfSelection = iCopyEndOffset;
	//	if (iEndOfSelection >= iStartOfSelection)
	//	{
	//		int i = 0;
	//		iDumpStart = iStartOfSelection;
	//		iDumpEnd = iEndOfSelection;
	//		std::vector<std::string> vDumpSize((iDumpEnd-iDumpStart)+1);
	//		vHexdoc = vDumpSize;
	//		vDumpSize = vEmpty;
	//		SetCursor (LoadCursor (NULL, IDC_WAIT));
	//		HWND progressdialog = CreateDialog(hInstance, MAKEINTRESOURCE (IDD_PROGRESSDIALOG),hwnd,ProgressDialogProc);
	//		SetWindowText(progressdialog,"Script Dump Preparation...");
	//		SetWindowText(GetDlgItem(progressdialog,IDC_PROGRESS1TITLE),"Queuing bytes...");
	//		progress1 = GetDlgItem(progressdialog,IDC_PROGRESS1);
	//		SetProgressRange(progress1,0,vHexdoc.size());
	//		if(vHexdoc.size() >= 10000)//this could be better
	//		{
	//			iIncrementStep = vHexdoc.size() / 1000;
	//		}
	//		else if(vHexdoc.size() >= 1000)//this could be better
	//		{
	//			iIncrementStep = vHexdoc.size() / 100;
	//		}
	//		else if(vHexdoc.size() >= 100)
	//		{
	//			iIncrementStep = vHexdoc.size() / 10;
	//		}
	//		else
	//		{
	//			iIncrementStep = 2; 
	//		}
	//		SetProgressStep(progress1,iIncrementStep);  
	//		for(i = iDumpStart;i<=iDumpEnd;i++)
	//		{
	//			iProgressPos++;
	//			if(progress1 != NULL && iProgressPos % iIncrementStep == 0)
	//			{
	//				StepProgress(progress1);	
	//			}
	//			vHexdoc[i - iDumpStart] = hex_char(FileBuffer[i]);
	//		}
	//		DestroyWindow(progressdialog);
	//		iProgressPos = 0;
	//		iIncrementStep = 0;
	//		progress1 = NULL;
	//		long filesize = vHexdoc.size();
	//		numbytes = vHexdoc.size();
	//		if(bDumpClean)
	//		{
	//			bCleanScript = true;
	//		}
	//		else
	//		{
	//			bCleanScript = false;
	//		}
	//		progressdialog = CreateDialog(hInstance, MAKEINTRESOURCE (IDD_2PROGRESSDIALOG),hwnd,ProgressDialogProc);
	//		SetWindowText(progressdialog,"Script Dump Progress...");
	//		SetWindowText(GetDlgItem(progressdialog,IDC_PROGRESS1TITLE),"Translating...");
	//		progress1 = GetDlgItem(progressdialog,IDC_PROGRESS1);
	//		progress2 = GetDlgItem(progressdialog,IDC_PROGRESS2);
	//		SetProgressRange(progress1,0,vHexdoc.size());
	//		if(vHexdoc.size() >= 10000)//this could be better
	//		{
	//			iIncrementStep = vHexdoc.size() / 1000;
	//		}
	//		else if(vHexdoc.size() >= 1000)//this could be better
	//		{
	//			iIncrementStep = vHexdoc.size() / 100;
	//		}
	//		else if(vHexdoc.size() >= 100)
	//		{
	//			iIncrementStep = vHexdoc.size() / 10;
	//		}
	//		else
	//		{
	//			iIncrementStep = 2; 
	//		}
	//		SetProgressStep(progress1,iIncrementStep);  
	//		translate(vHexdoc);
	//		SetProgressPos(progress1,numbytes);
	//		iProgressPos = 0;
	//		SetProgressRange(progress2,0,vHexdoc.size());
	//		if(vHexdoc.size() >= 10000)//this could be better
	//		{
	//			iIncrementStep = vHexdoc.size() / 1000;
	//		}
	//		else if(vHexdoc.size() >= 1000)//this could be better
	//		{
	//			iIncrementStep = vHexdoc.size() / 100;
	//		}
	//		else if(vHexdoc.size() >= 100)
	//		{
	//			iIncrementStep = vHexdoc.size() / 10;
	//		}
	//		else
	//		{
	//			iIncrementStep = 2; 
	//		}
	//		SetProgressStep(progress2,iIncrementStep);  
	//		SetWindowText(GetDlgItem(progressdialog,IDC_PROGRESS2TITLE),"Formatting...");
	//		enscript(vHexdoc);
	//		progress1 = NULL;
	//		progress2 = NULL;
	//		iIncrementStep = 0;
	//		iProgressPos = 0;
	//		DestroyWindow(progressdialog);
	//		bCleanScript = false;
	//		SetCursor (LoadCursor (NULL, IDC_ARROW));
	//		if(bDumpToFile)
	//		{
	//			fstream fs;
	//			fs.open(sFileName.c_str(),ios::out);
	//			if (!fs.fail())
	//			{
	//				
	//				if(bSeemsJ)
	//				{
	//					if(MessageBox(hwnd,((string) sName + " has detected that this may be a Japanese script.  You" +
	//					" have the option to combine characters and the punctuation characters that modify them into single characters." +
	//					"  Would you like to merge modified characters with their punctuation?").c_str(),LoadString(IDS_TITLE_NOTICE), MB_YESNO | MB_ICONQUESTION) == IDYES)
	//					{
	//						SetCursor (LoadCursor (NULL, IDC_WAIT));
	//						pwrite_script_file(fs,vHexdoc);
	//					}
	//					else
	//					{
	//						SetCursor (LoadCursor (NULL, IDC_WAIT));
	//						write_script_file(fs,vHexdoc);
	//					}
	//					bSeemsJ = false;
	//				}
	//				else
	//				{
	//					SetCursor (LoadCursor (NULL, IDC_WAIT));
	//					write_script_file(fs,vHexdoc);
	//				}
	//				SetCursor (LoadCursor (NULL, IDC_ARROW));
	//				fs.close();
	//				MessageBox (hwnd, ("Script dumped sucessfully to " + sFileName + "\n\n" + stringvalue(filesize) + " tile-bytes have been dumped.").c_str(), "Script Dump Complete", MB_OK);
	//				dumps++;
	//			}
	//			else
	//			{
	//				MessageBox (hwnd, "Could not save file.", "Script dump error:", MB_OK | MB_ICONERROR);
	//				fs.close();
	//			}
	//			
	//		}
	//		else
	//		{
	//			if(bDumpClean)
	//			{
	//				MessageBox(hwnd,"'#' is defined in your table file so dump to screen is not allowed!",LoadString(IDS_TITLE_NOTICE),MB_OK | MB_ICONINFORMATION);
	//			}
	//			bool oldbmark = bByteMark;
	//			if (!bDumpClean && DialogBox (hInstance, MAKEINTRESOURCE (IDD_VIEWSCRIPTDIALOG), hwnd, (DLGPROC) ViewScriptDialogProc) != FALSE)
	//			{
	//				if(bReadOnly)
	//				{
	//					MessageBox(hwnd,"File cannot be changed in read-only mode!","Script reinsertion error:", MB_OK | MB_ICONERROR);
	//					return 0;
	//				}
	//				SetCursor (LoadCursor (NULL, IDC_WAIT));
	//				HWND progressdialog = CreateDialog(hInstance, MAKEINTRESOURCE (IDD_2PROGRESSDIALOG),hwnd,ProgressDialogProc);
	//				SetWindowText(progressdialog,"Script Replacement Progress...");
	//				SetWindowText(GetDlgItem(progressdialog,IDC_PROGRESS1TITLE),"Removing Formatting...");
	//				progress1 = GetDlgItem(progressdialog,IDC_PROGRESS1);
	//				progress2 = GetDlgItem(progressdialog,IDC_PROGRESS2);
	//				int numbytes2 = vHexdoc.size();
	//				SetProgressRange(progress1,0,vHexdoc.size());
	//				if(vHexdoc.size() >= 10000)//this could be better
	//				{
	//					iIncrementStep = vHexdoc.size() / 1000;
	//				}
	//				else if(vHexdoc.size() >= 1000)//this could be better
	//				{
	//					iIncrementStep = vHexdoc.size() / 100;
	//				}
	//				else if(vHexdoc.size() >= 100)
	//				{
	//					iIncrementStep = vHexdoc.size() / 10;
	//				}
	//				else
	//				{
	//					iIncrementStep = 2; 
	//				}
	//				SetProgressStep(progress1,iIncrementStep);  
	//				descript(vHexdoc);
	//				SetProgressPos(progress1,numbytes2);
	//				iProgressPos = 0;
	//				SetProgressRange(progress2,0,vHexdoc.size());
	//				if(vHexdoc.size() >= 10000)//this could be better
	//				{
	//					iIncrementStep = vHexdoc.size() / 1000;
	//				}
	//				else if(vHexdoc.size() >= 1000)//this could be better
	//				{
	//					iIncrementStep = vHexdoc.size() / 100;
	//				}
	//				else if(vHexdoc.size() >= 100)
	//				{
	//					iIncrementStep = vHexdoc.size() / 10;
	//				}
	//				else
	//				{
	//					iIncrementStep = 2; 
	//				}
	//				SetProgressStep(progress2,iIncrementStep);  
	//				SetWindowText(GetDlgItem(progressdialog,IDC_PROGRESS2TITLE),"Translating...");
	//				detranslate(vHexdoc);
	//				progress1 = NULL;
	//				progress2 = NULL;
	//				iIncrementStep = 0;
	//				iProgressPos = 0;
	//				DestroyWindow(progressdialog);
	//				int tblock = -1;
	//				if((int)vHexdoc.size() > numbytes)
	//				{
	//					tblock = MessageBox(hwnd,((std::string) "The number of bytes you are inserting exceeds the amount you dumped by " +
	//						stringvalue((int)vHexdoc.size() - numbytes) + " bytes." + 
	//						"\nThe extra bytes will be written AFTER the originally selected dump overwriting existing bytes!" +
	//						"\nAre you sure you want to do this?").c_str(),"WARNING!",MB_OKCANCEL | MB_ICONWARNING);
	//					switch(tblock)
	//					{
	//					case IDOK:
	//						{
	//							if(iDumpStart + (int)vHexdoc.size() > FileBuffer.Length())
	//							{
	//								MessageBox(hwnd,((std::string) "The number of bytes you are replacing exceeds the end of the file!" +
	//									"\r\nThe replacement will stop when the end of the file is reached.").c_str(),LoadString(IDS_TITLE_NOTICE),MB_OK | MB_ICONINFORMATION);
	//							}
	//							progressdialog = CreateDialog(hInstance, MAKEINTRESOURCE (IDD_PROGRESSDIALOG),hwnd,ProgressDialogProc);
	//							SetWindowText(progressdialog,"Script Replacement Progress...");
	//							SetWindowText(GetDlgItem(progressdialog,IDC_PROGRESS1TITLE),"Replacing bytes...");
	//							progress1 = GetDlgItem(progressdialog,IDC_PROGRESS1);
	//							SetProgressRange(progress1,0,vHexdoc.size());
	//							if(vHexdoc.size() >= 10000)//this could be better
	//							{
	//								iIncrementStep = vHexdoc.size() / 1000;
	//							}
	//							else if(vHexdoc.size() >= 1000)//this could be better
	//							{
	//								iIncrementStep = vHexdoc.size() / 100;
	//							}
	//							else if(vHexdoc.size() >= 100)
	//							{
	//								iIncrementStep = vHexdoc.size() / 10;
	//							}
	//							else
	//							{
	//								iIncrementStep = 2; 
	//							}
	//							SetProgressStep(progress1,iIncrementStep);  
	//							for(i = iDumpStart;i < FileBuffer.Length() && i<iDumpStart + (int)vHexdoc.size();i++)
	//							{
	//								iProgressPos++;
	//								if(progress1 != NULL && iProgressPos % iIncrementStep == 0)
	//								{
	//									StepProgress(progress1);
	//								}
	//								FileBuffer[i] = char_hex(vHexdoc[i - iDumpStart]);
	//								vChanges[i] = COLORCHANGE;
	//							}
	//							DestroyWindow(progressdialog);
	//							iProgressPos = 0;
	//							iIncrementStep = 0;
	//							progress1 = NULL;
	//							inserts++;
	//							iFileChanged = TRUE;
	//							break;
	//						}
	//					case IDCANCEL:
	//						{
	//							MessageBox(hwnd,"No bytes have been changed.",LoadString(IDS_TITLE_NOTICE),MB_ICONINFORMATION);
	//							break;
	//						}
	//					}
	//				}
	//				else if((int)vHexdoc.size() < numbytes)
	//				{
	//					tblock = MessageBox(hwnd,((std::string) "The number of bytes you are inserting is less than the amount you dumped by " +
	//						stringvalue((int)numbytes - (int)vHexdoc.size()) + " bytes." + 
	//						"\nDo you wish to overwrite the remainder of the originally selected dump with '00'?" +
	//						"\nIf you select no, the remaining bytes will be left as is.").c_str(),LoadString(IDS_TITLE_NOTICE),MB_YESNO | MB_ICONWARNING);
	//					switch(tblock)
	//					{
	//					case IDYES:
	//						{
	//							progressdialog = CreateDialog(hInstance, MAKEINTRESOURCE (IDD_PROGRESSDIALOG),hwnd,ProgressDialogProc);
	//							SetWindowText(progressdialog,"Script Replacement Progress...");
	//							SetWindowText(GetDlgItem(progressdialog,IDC_PROGRESS1TITLE),"Replacing bytes...");
	//							progress1 = GetDlgItem(progressdialog,IDC_PROGRESS1);
	//							SetProgressRange(progress1,0,numbytes);
	//							if(vHexdoc.size() >= 10000)//this could be better
	//							{
	//								iIncrementStep = vHexdoc.size() / 1000;
	//							}
	//							else if(vHexdoc.size() >= 1000)//this could be better
	//							{
	//								iIncrementStep = vHexdoc.size() / 100;
	//							}
	//							else if(vHexdoc.size() >= 100)
	//							{
	//								iIncrementStep = vHexdoc.size() / 10;
	//							}
	//							else
	//							{
	//								iIncrementStep = 2; 
	//							}
	//							SetProgressStep(progress1,iIncrementStep);  
	//							for(i = 0;i<(int)vHexdoc.size();i++)
	//							{
	//								iProgressPos++;
	//								if(progress1 != NULL && iProgressPos % iIncrementStep == 0)
	//								{
	//									StepProgress(progress1);
	//								}
	//								FileBuffer[iDumpStart + i] = char_hex(vHexdoc[i]);
	//								vChanges[iDumpStart + i] = COLORCHANGE;
	//							}
	//							difference = iDumpStart + i;
	//							for(i = 0;i <(numbytes - (int)vHexdoc.size());i++)
	//							{
	//								iProgressPos++;
	//								if(progress1 != NULL && iProgressPos % iIncrementStep == 0)
	//								{
	//									StepProgress(progress1);
	//								}
	//								FileBuffer[difference + i] = char_hex("00");
	//								vChanges[difference + i] = COLORCHANGE;
	//							}
	//							DestroyWindow(progressdialog);
	//							iProgressPos = 0;
	//							iIncrementStep = 0;
	//							progress1 = NULL;
	//							inserts++;
	//							iFileChanged = TRUE;
	//							break;
	//						}
	//					case IDNO:
	//						{
	//							progressdialog = CreateDialog(hInstance, MAKEINTRESOURCE (IDD_PROGRESSDIALOG),hwnd,ProgressDialogProc);
	//							SetWindowText(progressdialog,"Script Replacement Progress...");
	//							SetWindowText(GetDlgItem(progressdialog,IDC_PROGRESS1TITLE),"Replacing bytes...");
	//							progress1 = GetDlgItem(progressdialog,IDC_PROGRESS1);
	//							SetProgressRange(progress1,0,vHexdoc.size());
	//							if(vHexdoc.size() >= 10000)//this could be better
	//							{
	//								iIncrementStep = vHexdoc.size() / 1000;
	//							}
	//							else if(vHexdoc.size() >= 1000)//this could be better
	//							{
	//								iIncrementStep = vHexdoc.size() / 100;
	//							}
	//							else if(vHexdoc.size() >= 100)
	//							{
	//								iIncrementStep = vHexdoc.size() / 10;
	//							}
	//							else
	//							{
	//								iIncrementStep = 2; 
	//							}
	//							SetProgressStep(progress1,iIncrementStep);  
	//							for(i = 0;i<(int)vHexdoc.size();i++)
	//							{
	//								iProgressPos++;
	//								if(progress1 != NULL && iProgressPos % iIncrementStep == 0)
	//								{
	//									StepProgress(progress1);
	//								}
	//								FileBuffer[iDumpStart + i] = char_hex(vHexdoc[i]);
	//								vChanges[iDumpStart + i] = COLORCHANGE;
	//							}
	//							DestroyWindow(progressdialog);
	//							iProgressPos = 0;
	//							iIncrementStep = 0;
	//							progress1 = NULL;
	//							inserts++;
	//							iFileChanged = TRUE;
	//							break;
	//						}
	//					}
	//					
	//				}
	//				else
	//				{
	//					progressdialog = CreateDialog(hInstance, MAKEINTRESOURCE (IDD_PROGRESSDIALOG),hwnd,ProgressDialogProc);
	//					SetWindowText(progressdialog,"Script Replacement Progress...");
	//					SetWindowText(GetDlgItem(progressdialog,IDC_PROGRESS1TITLE),"Replacing bytes...");
	//					progress1 = GetDlgItem(progressdialog,IDC_PROGRESS1);
	//					SetProgressRange(progress1,0,vHexdoc.size());
	//					if(vHexdoc.size() >= 10000)//this could be better
	//					{
	//						iIncrementStep = vHexdoc.size() / 1000;
	//					}
	//					else if(vHexdoc.size() >= 1000)//this could be better
	//					{
	//						iIncrementStep = vHexdoc.size() / 100;
	//					}
	//					else if(vHexdoc.size() >= 100)
	//					{
	//						iIncrementStep = vHexdoc.size() / 10;
	//					}
	//					else
	//					{
	//						iIncrementStep = 2; 
	//					}
	//					SetProgressStep(progress1,iIncrementStep);  
	//					for(i = 0;i<(int)vHexdoc.size();i++)
	//					{
	//						iProgressPos++;
	//						if(progress1 != NULL && iProgressPos % iIncrementStep == 0)
	//						{
	//							StepProgress(progress1);
	//						}
	//						FileBuffer[iDumpStart + i] = char_hex(vHexdoc[i]);
	//						vChanges[iDumpStart + i] = COLORCHANGE;
	//					}
	//					DestroyWindow(progressdialog);
	//					iProgressPos = 0;
	//					iIncrementStep = 0;
	//					progress1 = NULL;
	//					inserts++;
	//					iFileChanged = TRUE;
	//				}
	//				bByteMark = oldbmark;
	//				vHexdoc = vEmpty;
	//				sScriptDump = "";
	//				iDumpStart = 0;
	//				iDumpEnd = 0;
	//				SetCursor (LoadCursor (NULL, IDC_ARROW));
	//				repaint();
	//			}

	//		}
	//	}
	//	else
	//	{
	//		MessageBoxA (hwnd, "Ending offset is smaller than starting offset.", "Script dump error:", MB_OK | MB_ICONERROR);
	//	}

	//		
	//}
	//iDumpStart = 0;
	//iDumpEnd = 0;
	//adjust_view_for_selection ();
	return 1;
}

int Translhextion::replace_script ()
{
	//long numbytes = 0;
	//long difference = 0;
	//long actualreplace = 0;
	//if (!bSelected)
	//{
	//	iCopyStartOffset = iCurrentByte;
	//	iCopyEndOffset = iCurrentByte;
	//}
	//else
	//{
	//	if (iEndOfSelection >= iStartOfSelection)
	//	{
	//		iCopyStartOffset = iStartOfSelection;
	//		iCopyEndOffset = iEndOfSelection;
	//	}
	//	else
	//	{
	//		iCopyStartOffset = iEndOfSelection;
	//		iCopyEndOffset = iStartOfSelection;
	//	}
	//}

	//if (DialogBox (hInstance, MAKEINTRESOURCE (IDD_REPLACESCRIPTDIALOG), hwnd, (DLGPROC) ScriptReplaceDialogProc) != FALSE)
	//{
	//	
	//	iStartOfSelection = iCopyStartOffset;
	//	iEndOfSelection = iCopyEndOffset;
	//	if (iEndOfSelection >= iStartOfSelection)
	//	{
	//		fstream fs;
	//		fs.open(sFileName.c_str(),ios::in);
	//		vHexdoc = vEmpty;
	//		if(!fs.fail())
	//		{
	//			int i = 0;
	//			read_script_file(fs,vHexdoc);
	//			fs.close();
	//			iDumpStart = iStartOfSelection;
	//			iDumpEnd = iEndOfSelection;
	//			SetCursor (LoadCursor (NULL, IDC_WAIT));
	//			HWND progressdialog = CreateDialog(hInstance, MAKEINTRESOURCE (IDD_2PROGRESSDIALOG),hwnd,ProgressDialogProc);
	//			SetWindowText(progressdialog,"Script Replacement Progress...");
	//			SetWindowText(GetDlgItem(progressdialog,IDC_PROGRESS1TITLE),"Removing Formatting...");
	//			progress1 = GetDlgItem(progressdialog,IDC_PROGRESS1);
	//			progress2 = GetDlgItem(progressdialog,IDC_PROGRESS2);
	//			numbytes = vHexdoc.size();
	//			SetProgressRange(progress1,0,vHexdoc.size());
	//			if(vHexdoc.size() >= 10000)//this could be better
	//			{
	//				iIncrementStep = vHexdoc.size() / 1000;
	//			}
	//			else if(vHexdoc.size() >= 1000)//this could be better
	//			{
	//				iIncrementStep = vHexdoc.size() / 100;
	//			}
	//			else if(vHexdoc.size() >= 100)
	//			{
	//				iIncrementStep = vHexdoc.size() / 10;
	//			}
	//			else
	//			{
	//				iIncrementStep = 2; 
	//			}
	//			SetProgressStep(progress1,iIncrementStep);  
	//			descript(vHexdoc);
	//			SetProgressPos(progress1,numbytes);
	//			iProgressPos = 0;
	//			SetProgressRange(progress2,0,vHexdoc.size());
	//			if(vHexdoc.size() >= 10000)//this could be better
	//			{
	//				iIncrementStep = vHexdoc.size() / 1000;
	//			}
	//			else if(vHexdoc.size() >= 1000)//this could be better
	//			{
	//				iIncrementStep = vHexdoc.size() / 100;
	//			}
	//			else if(vHexdoc.size() >= 100)
	//			{
	//				iIncrementStep = vHexdoc.size() / 10;
	//			}
	//			else
	//			{
	//				iIncrementStep = 2; 
	//			}
	//			SetProgressStep(progress2,iIncrementStep);  
	//			SetWindowText(GetDlgItem(progressdialog,IDC_PROGRESS2TITLE),"Translating...");
	//			detranslate(vHexdoc);
	//			progress1 = NULL;
	//			progress2 = NULL;
	//			iIncrementStep = 0;
	//			iProgressPos = 0;
	//			DestroyWindow(progressdialog);
	//			long filesize = vHexdoc.size();
	//			actualreplace = filesize;
	//			numbytes = vHexdoc.size();
	//			progressdialog = CreateDialog(hInstance, MAKEINTRESOURCE (IDD_PROGRESSDIALOG),hwnd,ProgressDialogProc);
	//			SetWindowText(progressdialog,"Script Replacement Progress...");
	//			SetWindowText(GetDlgItem(progressdialog,IDC_PROGRESS1TITLE),"Replacing bytes...");
	//			progress1 = GetDlgItem(progressdialog,IDC_PROGRESS1);
	//			if(bReplaceToOffset && bPadBytes)
	//			{
	//				SetProgressRange(progress1,0,(iDumpEnd - iDumpStart)+1);
	//			}
	//			else if(bReplaceToOffset && !bPadBytes)
	//			{
	//				SetProgressRange(progress1,0,(int)vHexdoc.size() < (int)((iDumpEnd - iDumpStart)+1) ? (int)vHexdoc.size() : ((iDumpEnd - iDumpStart)+1));
	//			}
	//			else
	//			{
	//				SetProgressRange(progress1,0,vHexdoc.size());
	//			}
	//			if(vHexdoc.size() >= 10000)//this could be better
	//			{
	//				iIncrementStep = vHexdoc.size() / 1000;
	//			}
	//			else if(vHexdoc.size() >= 1000)//this could be better
	//			{
	//				iIncrementStep = vHexdoc.size() / 100;
	//			}
	//			else if(vHexdoc.size() >= 100)
	//			{
	//				iIncrementStep = vHexdoc.size() / 10;
	//			}
	//			else
	//			{
	//				iIncrementStep = 2; 
	//			}
	//			SetProgressStep(progress1,iIncrementStep);  
	//			if(bReplaceToOffset)
	//			{
	//				if(bPadBytes)
	//				{
	//					for(i = 0;((i + iDumpStart)<= iDumpEnd) && (i<(int)vHexdoc.size()) && ((i + iDumpStart) < FileBuffer.Length());i++)
	//					{
	//						iProgressPos++;
	//						if(progress1 != NULL && iProgressPos % iIncrementStep == 0)
	//						{
	//							StepProgress(progress1);
	//						}
	//						FileBuffer[iDumpStart + i] = char_hex(vHexdoc[i]);
	//						vChanges[iDumpStart + i] = COLORCHANGE;
	//					}
	//					difference = iDumpStart + i;
	//					for(i = 0;((difference + i) <= iDumpEnd) && ((difference + i) < FileBuffer.Length());i++)
	//					{
	//						iProgressPos++;
	//						if(progress1 != NULL && iProgressPos % iIncrementStep == 0)
	//						{
	//							StepProgress(progress1);
	//						}
	//						FileBuffer[difference + i] = char_hex("00");
	//						vChanges[difference + i] = COLORCHANGE;
	//					}
	//					if(iDumpEnd - iDumpStart < filesize)
	//					{
	//						filesize = iDumpEnd - iDumpStart + 1;
	//					}
	//				}
	//				else
	//				{
	//					for(i = 0;((i + iDumpStart) <= iDumpEnd) && (i<(int)vHexdoc.size()) && ((i + iDumpStart) < FileBuffer.Length());i++)
	//					{
	//						iProgressPos++;
	//						if(progress1 != NULL && iProgressPos % iIncrementStep == 0)
	//						{
	//							StepProgress(progress1);
	//						}
	//						FileBuffer[iDumpStart + i] = char_hex(vHexdoc[i]);
	//						vChanges[iDumpStart + i] = COLORCHANGE;
	//					}
	//					if(iDumpEnd - iDumpStart < filesize)
	//					{
	//						filesize = iDumpEnd - iDumpStart + 1;
	//					}
	//				}
	//			}
	//			else
	//			{
	//				if(iDumpStart + (int)vHexdoc.size() > FileBuffer.Length())
	//				{
	//					MessageBox(hwnd,((string) "The number of bytes you are replacing exceeds the end of the file!" +
	//						"\r\nThe replacement will stop when the end of the file is reached.").c_str(),LoadString(IDS_TITLE_NOTICE),MB_OK | MB_ICONINFORMATION);
	//				}
	//				for(i = 0;(i<(int)vHexdoc.size()) && ((i + iDumpStart) < FileBuffer.Length());i++)
	//				{
	//					iProgressPos++;
	//					if(progress1 != NULL && iProgressPos % iIncrementStep == 0)
	//					{
	//						StepProgress(progress1);
	//					}
	//					FileBuffer[iDumpStart + i] = char_hex(vHexdoc[i]);
	//					vChanges[iDumpStart + i] = COLORCHANGE;
	//				}
	//			}
	//			DestroyWindow(progressdialog);
	//			iProgressPos = 0;
	//			iIncrementStep = 0;
	//			progress1 = NULL;
	//			inserts++;
	//			SetCursor (LoadCursor (NULL, IDC_ARROW));
	//			bReplaceToOffset = false;
	//			bPadBytes = false;
	//			vHexdoc = vEmpty;
	//			iDumpStart = 0;
	//			iDumpEnd = 0;
	//			iFileChanged = TRUE;
	//			repaint();
	//			MessageBox(hwnd,(stringvalue(filesize) + " tile-bytes have been replaced.").c_str(),LoadString(IDS_TITLE_NOTICE),MB_OK | MB_ICONINFORMATION);
	//		}
	//		else
	//		{
	//			fs.close();
	//			MessageBox(hwnd,"Error occurred while reading from script file.","Script replace error:",MB_OK | MB_ICONERROR);
	//		}		
	//	}
	//	else
	//	{
	//		MessageBox (hwnd, "Ending offset is smaller than starting offset.", "Script replace error:", MB_OK | MB_ICONERROR);
	//	}	
	//}
	//iDumpStart = 0;
	//iDumpEnd = 0;
	//adjust_view_for_selection ();
	return 1;
}


void Translhextion::optimize_script_file()
{
	//string question;
	//long numbytes = 0;
	//TCHAR cFileName[_MAX_PATH];
	//char szTitleName[_MAX_FNAME + _MAX_EXT];
	//cFileName[0] = '\0';
	//OPENFILENAME ofn;
	//ofn.lStructSize = sizeof (OPENFILENAME);
	//ofn.hwndOwner = hwnd;
	//ofn.hInstance = NULL;
	//ofn.lpstrFilter = "Text Files (*.TXT)\0*.TXT\0Script Files (*.SCP)\0*.SCP\0All Files (*.*)\0*.*\0\0";
	//ofn.lpstrCustomFilter = NULL;
	//ofn.nMaxCustFilter = 0;
	//ofn.nFilterIndex = 0;
	//ofn.lpstrFile = cFileName;
	//ofn.nMaxFile = _MAX_PATH;
	//ofn.lpstrFileTitle = szTitleName;
	//ofn.nMaxFileTitle = _MAX_FNAME + _MAX_EXT;
	//ofn.lpstrInitialDir = NULL;
	//ofn.lpstrTitle = "Open Script File to Optimize";
	//ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_FILEMUSTEXIST;
	//ofn.nFileOffset = 0;
	//ofn.nFileExtension = 0;
	//ofn.lpstrDefExt = NULL;
	//ofn.lCustData = 0L;
	//ofn.lpfnHook = NULL;
	//ofn.lpTemplateName = NULL;
	//if (GetOpenFileName (&ofn))
	//{
	//	sFileName = (string) cFileName;
	//	fstream fs;
	//	fs.open(sFileName.c_str(),ios::in);
	//	if(!fs.fail())
	//	{
	//		bool oldbmark = bByteMark;
	//		vHexdoc = vEmpty;
	//		SetCursor (LoadCursor (NULL, IDC_WAIT));
	//		read_script_file(fs,vHexdoc);
	//		SetCursor (LoadCursor (NULL, IDC_ARROW));
	//		fs.close();
	//		OPENFILENAME ofn2;
	//		szTitleName[0] =cFileName[0] = '\0';
	//		ofn2.lStructSize = sizeof (OPENFILENAME);
	//		ofn2.hwndOwner = hwnd;
	//		ofn2.hInstance = NULL;
	//		ofn2.lpstrFilter = "Text Files (*.TXT)\0*.TXT\0Script Files (*.SCP)\0*.SCP\0All Files (*.*)\0*.*\0\0";
	//		ofn2.lpstrCustomFilter = NULL;
	//		ofn2.nMaxCustFilter = 0;
	//		ofn2.nFilterIndex = 0;
	//		ofn2.lpstrFile = cFileName;
	//		ofn2.nMaxFile = _MAX_PATH;
	//		ofn2.lpstrFileTitle = szTitleName;
	//		ofn2.nMaxFileTitle = _MAX_FNAME + _MAX_EXT;
	//		ofn2.lpstrInitialDir = NULL;
	//		ofn2.lpstrTitle = "Save Optimized Script As";
	//		ofn2.Flags = OFN_HIDEREADONLY | OFN_CREATEPROMPT | OFN_OVERWRITEPROMPT;
	//		ofn2.nFileOffset = 0;
	//		ofn2.nFileExtension = 0;
	//		ofn2.lpstrDefExt = NULL;
	//		ofn2.lCustData = 0L;
	//		ofn2.lpfnHook = NULL;
	//		ofn2.lpTemplateName = NULL;
	//		if (GetSaveFileName (&ofn2))
	//		{
	//			int cur = strlen(cFileName) - 4;
	//			//if(uppercase(((string) cFileName).substr(((string) cFileName).length()-4,4)) == ".TXT")
	//			//{
	//			//	sFileName = (string) cFileName;
	//			//}
	//			//else
	//			//{
	//			//	sFileName = (string) strcat(cFileName,".txt");
	//			//}
	//			sFileName=FixFilename(cFileName,".TXT");
	//			fs.open(sFileName.c_str(),ios::out);
	//			if(!fs.fail())
	//			{
	//				SetCursor (LoadCursor (NULL, IDC_WAIT));
	//				HWND progressdialog = CreateDialog(hInstance, MAKEINTRESOURCE (IDD_6PROGRESSDIALOG),hwnd,ProgressDialogProc);
	//				SetWindowText(progressdialog,"Script Optimization Progress...");
	//				SetWindowText(GetDlgItem(progressdialog,IDC_PROGRESS1TITLE),"Removing Formatting...");
	//				progress1 = GetDlgItem(progressdialog,IDC_PROGRESS1);
	//				progress2 = GetDlgItem(progressdialog,IDC_PROGRESS2);
	//				SetProgressColor(progress1,RGB(255,0,0));
	//				SetProgressColor(progress2,RGB(255,128,0));
	//				numbytes = vHexdoc.size();
	//				SetProgressRange(progress1,0,vHexdoc.size());
	//				if(vHexdoc.size() >= 10000)//this could be better
	//				{
	//					iIncrementStep = vHexdoc.size() / 1000;
	//				}
	//				else if(vHexdoc.size() >= 1000)//this could be better
	//				{
	//					iIncrementStep = vHexdoc.size() / 100;
	//				}
	//				else if(vHexdoc.size() >= 100)
	//				{
	//					iIncrementStep = vHexdoc.size() / 10;
	//				}
	//				else
	//				{
	//					iIncrementStep = 2; 
	//				}
	//				SetProgressStep(progress1,iIncrementStep);  
	//				bByteMark = true;
	//				descript(vHexdoc);
	//				SetProgressPos(progress1,numbytes);
	//				iProgressPos = 0;
	//				numbytes = vHexdoc.size();
	//				SetProgressRange(progress2,0,vHexdoc.size());
	//				if(vHexdoc.size() >= 10000)//this could be better
	//				{
	//					iIncrementStep = vHexdoc.size() / 1000;
	//				}
	//				else if(vHexdoc.size() >= 1000)//this could be better
	//				{
	//					iIncrementStep = vHexdoc.size() / 100;
	//				}
	//				else if(vHexdoc.size() >= 100)
	//				{
	//					iIncrementStep = vHexdoc.size() / 10;
	//				}
	//				else
	//				{
	//					iIncrementStep = 2; 
	//				}
	//				SetProgressStep(progress2,iIncrementStep);  
	//				SetWindowText(GetDlgItem(progressdialog,IDC_PROGRESS2TITLE),"Translating...");
	//				detranslate(vHexdoc);
	//				SetProgressPos(progress2,numbytes);
	//				progress1 = NULL;
	//				progress2 = NULL;
	//				iIncrementStep = 0;
	//				iProgressPos = 0;
	//				long filesize = vHexdoc.size();
	//				bByteMark = false;
	//				SetWindowText(GetDlgItem(progressdialog,IDC_PROGRESS3TITLE),"Phase 1...");
	//				progress1 = GetDlgItem(progressdialog,IDC_PROGRESS3);
	//				progress2 = GetDlgItem(progressdialog,IDC_PROGRESS4);
	//				SetProgressColor(progress1,RGB(255,255,0));
	//				SetProgressColor(progress2,RGB(0,255,0));
	//				numbytes = vHexdoc.size();
	//				SetProgressRange(progress1,0,vHexdoc.size());
	//				if(vHexdoc.size() >= 10000)//this could be better
	//				{
	//					iIncrementStep = vHexdoc.size() / 1000;
	//				}
	//				else if(vHexdoc.size() >= 1000)//this could be better
	//				{
	//					iIncrementStep = vHexdoc.size() / 100;
	//				}
	//				else if(vHexdoc.size() >= 100)
	//				{
	//					iIncrementStep = vHexdoc.size() / 10;
	//				}
	//				else
	//				{
	//					iIncrementStep = 2; 
	//				}
	//				SetProgressStep(progress1,iIncrementStep);  
	//				translate(vHexdoc);
	//				SetProgressPos(progress1,numbytes);
	//				iProgressPos = 0;
	//				numbytes = vHexdoc.size();
	//				SetProgressRange(progress2,0,vHexdoc.size());
	//				if(vHexdoc.size() >= 10000)//this could be better
	//				{
	//					iIncrementStep = vHexdoc.size() / 1000;
	//				}
	//				else if(vHexdoc.size() >= 1000)//this could be better
	//				{
	//					iIncrementStep = vHexdoc.size() / 100;
	//				}
	//				else if(vHexdoc.size() >= 100)
	//				{
	//					iIncrementStep = vHexdoc.size() / 10;
	//				}
	//				else
	//				{
	//					iIncrementStep = 2; 
	//				}
	//				SetProgressStep(progress2,iIncrementStep);  
	//				SetWindowText(GetDlgItem(progressdialog,IDC_PROGRESS4TITLE),"Phase 2...");
	//				enscript(vHexdoc);
	//				SetProgressPos(progress2,numbytes);
	//				progress1 = NULL;
	//				progress2 = NULL;
	//				iIncrementStep = 0;
	//				iProgressPos = 0;
	//				SetWindowText(GetDlgItem(progressdialog,IDC_PROGRESS5TITLE),"Phase 3...");
	//				progress1 = GetDlgItem(progressdialog,IDC_PROGRESS5);
	//				progress2 = GetDlgItem(progressdialog,IDC_PROGRESS6);
	//				SetProgressColor(progress1,RGB(0,255,255));
	//				SetProgressColor(progress2,RGB(128,0,255));
	//				numbytes = vHexdoc.size();
	//				SetProgressRange(progress1,0,vHexdoc.size());
	//				if(vHexdoc.size() >= 10000)//this could be better
	//				{
	//					iIncrementStep = vHexdoc.size() / 1000;
	//				}
	//				else if(vHexdoc.size() >= 1000)//this could be better
	//				{
	//					iIncrementStep = vHexdoc.size() / 100;
	//				}
	//				else if(vHexdoc.size() >= 100)
	//				{
	//					iIncrementStep = vHexdoc.size() / 10;
	//				}
	//				else
	//				{
	//					iIncrementStep = 2; 
	//				}
	//				SetProgressStep(progress1,iIncrementStep);  
	//				descript(vHexdoc);
	//				SetProgressPos(progress1,numbytes);
	//				iProgressPos = 0;
	//				numbytes = vHexdoc.size();
	//				SetProgressRange(progress2,0,vHexdoc.size());
	//				if(vHexdoc.size() >= 10000)//this could be better
	//				{
	//					iIncrementStep = vHexdoc.size() / 1000;
	//				}
	//				else if(vHexdoc.size() >= 1000)//this could be better
	//				{
	//					iIncrementStep = vHexdoc.size() / 100;
	//				}
	//				else if(vHexdoc.size() >= 100)
	//				{
	//					iIncrementStep = vHexdoc.size() / 10;
	//				}
	//				else
	//				{
	//					iIncrementStep = 2; 
	//				}
	//				SetProgressStep(progress2,iIncrementStep);  
	//				SetWindowText(GetDlgItem(progressdialog,IDC_PROGRESS6TITLE),"Phase 4...");
	//				detranslate(vHexdoc);
	//				SetProgressPos(progress2,numbytes);
	//				progress1 = NULL;
	//				progress2 = NULL;
	//				iIncrementStep = 0;
	//				iProgressPos = 0;
	//				long filesize2 = vHexdoc.size();
	//				bByteMark = true;
	//				SetWindowText(GetDlgItem(progressdialog,IDC_PROGRESS7TITLE),"Translating...");
	//				progress1 = GetDlgItem(progressdialog,IDC_PROGRESS7);
	//				progress2 = GetDlgItem(progressdialog,IDC_PROGRESS8);
	//				numbytes = vHexdoc.size();
	//				SetProgressRange(progress1,0,vHexdoc.size());
	//				if(vHexdoc.size() >= 10000)//this could be better
	//				{
	//					iIncrementStep = vHexdoc.size() / 1000;
	//				}
	//				else if(vHexdoc.size() >= 1000)//this could be better
	//				{
	//					iIncrementStep = vHexdoc.size() / 100;
	//				}
	//				else if(vHexdoc.size() >= 100)
	//				{
	//					iIncrementStep = vHexdoc.size() / 10;
	//				}
	//				else
	//				{
	//					iIncrementStep = 2; 
	//				}
	//				SetProgressStep(progress1,iIncrementStep);  
	//				translate(vHexdoc);
	//				SetProgressPos(progress1,numbytes);
	//				iProgressPos = 0;
	//				numbytes = vHexdoc.size();
	//				SetProgressRange(progress2,0,vHexdoc.size());
	//				if(vHexdoc.size() >= 10000)//this could be better
	//				{
	//					iIncrementStep = vHexdoc.size() / 1000;
	//				}
	//				else if(vHexdoc.size() >= 1000)//this could be better
	//				{
	//					iIncrementStep = vHexdoc.size() / 100;
	//				}
	//				else if(vHexdoc.size() >= 100)
	//				{
	//					iIncrementStep = vHexdoc.size() / 10;
	//				}
	//				else
	//				{
	//					iIncrementStep = 2; 
	//				}
	//				SetProgressStep(progress2,iIncrementStep);  
	//				SetWindowText(GetDlgItem(progressdialog,IDC_PROGRESS8TITLE),"Formatting...");
	//				enscript(vHexdoc);
	//				SetProgressPos(progress2,numbytes);
	//				progress1 = NULL;
	//				progress2 = NULL;
	//				iIncrementStep = 0;
	//				iProgressPos = 0;
	//				bByteMark = oldbmark;
	//				DestroyWindow(progressdialog);
	//				write_script_file(fs,vHexdoc);
	//				SetCursor (LoadCursor (NULL, IDC_ARROW));
	//				fs.close();
	//				optimized++;
	//				ppair.x = filesize;
	//				ppair.y = filesize2;
	//				DialogBox (hInstance, MAKEINTRESOURCE (IDD_OPTIMIZERESULTSDIALOG), hwnd, (DLGPROC) InfoDialogProc);
	//				//SetFocus(progressdialog);
	//				//SetWindowText(progressdialog,"Script Optimization Progress...");
	//				//MessageBox(hwnd,("The input script file had " + stringvalue(filesize) + " tile-bytes." +
	//				//	"\nThe output script file has been crunched to " + stringvalue(filesize2) + " tile-bytes.").c_str(),LoadString(IDS_TITLE_NOTICE),MB_OK | MB_ICONINFORMATION);
	//				progress1 = NULL;
	//				progress2 = NULL;
	//				iIncrementStep = 0;
	//				iProgressPos = 0;
	//			}
	//			else
	//			{
	//				MessageBox(hwnd,"Error occurred while creating output script file.","Optimize script error:",MB_OK | MB_ICONWARNING);
	//				fs.close();
	//				return;
	//			}	
	//		}
	//		
	//	}
	//	else
	//	{
	//		MessageBox(hwnd,"Error occurred while reading input script file.","Optimize script error:",MB_OK | MB_ICONWARNING);
	//		fs.close();
	//		return;
	//	}
	//}
}

//OPTIONS
int Translhextion::view_settings()
{
	TxtEditName = sTexteditorName;
	iBPLSetting = iBytesPerLine;
	bAutomaticXAdjust = bAutomaticBPL;
	iOffsetLengthSetting = iOffsetLength;
	bUnsignedViewSetting = bUnsignedView;
	iOpenReadOnlySetting = bOpenReadOnly;

	iCharacterSetting = iCharacterSet;
	iFontSizeSetting = iFontSize;

	CSettingsDlg dlg(*this);

	if (dlg.DoModal()/*DialogBox (hInstance, MAKEINTRESOURCE (IDD_VIEWSETTINGSDIALOG), hwnd, (DLGPROC) ViewSettingsDialogProc)*/)
	{
		sTexteditorName = TxtEditName;
		if (iOffsetLength>0 && iOffsetLength<=8)
			iOffsetLength = iOffsetLengthSetting;
		iBytesPerLine = iBPLSetting;
		bOldAutomaticBPL = false;
		if(iBytesPerLine > 1 && iBytesPerLine % 2 != 0)
			iBytesPerLine--;
		bAutomaticBPL = bAutomaticXAdjust;
		bUnsignedView = bUnsignedViewSetting;
		bOpenReadOnly = iOpenReadOnlySetting;
		
		iCharacterSet = iCharacterSetting;
		iFontSize = iFontSizeSetting;
		save_ini_data ();
		update_size_change ();
		kill_focus ();
		set_focus ();
	}
	return 1;
}


int Translhextion::color_settings ()
{
	CColorSettingsDlg dlg(*this);
	if (dlg.DoModal()==IDOK)
	{
		iSelBkColorValue = cSelBkColor;
		iSelTextColorValue = cSelTextColor;
		iBookmarkColor = cBookmarkColor;
		iTextColorValue = cTextColor;
		iBkColorValue = cBkColor;
		iTextColorEValue = cTextColorE;
		iTextColorOValue = cTextColorO;
		iSepColorValue = cSepColor;
		iChangesColorValue = cChangesColor;
		iDTEColorValue = cDTEColor;
		iHighlightColorValue = cHighlightColor;
		save_ini_data ();
		update_size_change ();
		repaint ();
	}
	return 0;
}


int Translhextion::binarymode ()
{
	iBinaryModeSetting = iBinaryMode;
	if (DialogBox (hInstance, MAKEINTRESOURCE (IDD_BINARYMODEDIALOG), *this, (DLGPROC) BinaryModeDialogProc))
	{
		iBinaryMode = iBinaryModeSetting;
		repaint ();
	}
	return 1;
}

int Translhextion::offsetmode ()
{
	
	if (DialogBox (hInstance, MAKEINTRESOURCE (IDD_OFFSETMODEDIALOG), *this, (DLGPROC) OffsetModeDialogProc))
	{
		
		repaint ();
	}
	return 1;
}

